<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 5.4.0">
  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">


<link rel="stylesheet" href="/lib/font-awesome/css/all.min.css">

<script id="hexo-configurations">
    var NexT = window.NexT || {};
    var CONFIG = {"hostname":"vchao.top","root":"/","scheme":"Muse","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":false,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":false,"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
  </script>

  <meta name="description" content="怀揣好奇，梦想改变世界的菜鸟极客">
<meta property="og:type" content="website">
<meta property="og:title" content="乘风破浪">
<meta property="og:url" content="http://vchao.top/page/4/index.html">
<meta property="og:site_name" content="乘风破浪">
<meta property="og:description" content="怀揣好奇，梦想改变世界的菜鸟极客">
<meta property="og:locale" content="zh_CN">
<meta property="article:author" content="vchao">
<meta name="twitter:card" content="summary">

<link rel="canonical" href="http://vchao.top/page/4/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome : true,
    isPost : false,
    lang   : 'zh-CN'
  };
</script>

  <title>乘风破浪</title>
  






  <noscript>
  <style>
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <div class="container use-motion">
    <div class="headband"></div>

    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏">
      <span class="toggle-line toggle-line-first"></span>
      <span class="toggle-line toggle-line-middle"></span>
      <span class="toggle-line toggle-line-last"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <h1 class="site-title">乘风破浪</h1>
      <span class="logo-line-after"><i></i></span>
    </a>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
    </div>
  </div>
</div>




<nav class="site-nav">
  <ul id="menu" class="main-menu menu">
        <li class="menu-item menu-item-home">

    <a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a>

  </li>
        <li class="menu-item menu-item-archives">

    <a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档</a>

  </li>
  </ul>
</nav>




</div>
    </header>

    
  <div class="back-to-top">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>


    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          

          <div class="content index posts-expand">
            
      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://vchao.top/2018/04/12/%E6%89%8B%E6%8A%8A%E6%89%8B%E5%B8%A6%E4%BD%A0%E6%92%B8%E4%B8%80%E4%B8%AA%E6%A0%A1%E5%9B%ADAPP%EF%BC%88%E4%B8%80%EF%BC%89%EF%BC%9A%E9%A1%B9%E7%9B%AE%E7%AE%80%E4%BB%8B/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="vchao">
      <meta itemprop="description" content="怀揣好奇，梦想改变世界的菜鸟极客">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="乘风破浪">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/2018/04/12/%E6%89%8B%E6%8A%8A%E6%89%8B%E5%B8%A6%E4%BD%A0%E6%92%B8%E4%B8%80%E4%B8%AA%E6%A0%A1%E5%9B%ADAPP%EF%BC%88%E4%B8%80%EF%BC%89%EF%BC%9A%E9%A1%B9%E7%9B%AE%E7%AE%80%E4%BB%8B/" class="post-title-link" itemprop="url">手把手带你撸一个校园APP（一）：项目简介</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2018-04-12 17:51:40" itemprop="dateCreated datePublished" datetime="2018-04-12T17:51:40+08:00">2018-04-12</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="far fa-calendar-check"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2021-08-25 22:37:20" itemprop="dateModified" datetime="2021-08-25T22:37:20+08:00">2021-08-25</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Android/" itemprop="url" rel="index"><span itemprop="name">Android</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <blockquote>
<p>这个项目很早之前就在做，是为我大学母校（河北科技师范学院）做的一个项目，所以还是有很深的感情的。整体项目基于 Bmob 后端云来实现，其实功能和技术都并不算复杂，自己记录一下，也给需要的朋友们提供一些参考和借鉴。大神们还请绕路了。</p>
</blockquote>
<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>平常空余时间并不算多，本项目内容和知识点也有些杂，所以打算分成若干篇来写。本篇只是一些简介，方便朋友们对这个项目有个大概了解。本项目也大量参考了网上的技术博客和图片页面设计，在此真诚地向他们进行感谢。（参考内容将在文末一一列举）</p>
<h4 id="系列文章"><a href="#系列文章" class="headerlink" title="系列文章"></a>系列文章</h4><p>我确实太懒了，倒置这个系列拖了很久了，以至于有读者说我是不是嫖娼被抓起来了~~唉，略微无奈<br>Github地址： <a target="_blank" rel="noopener" href="https://github.com/zhengweichao/Hevttc">科师有约校园APP</a></p>
<p>暂定目录如下，已完成的会附上链接：</p>
<ol>
<li><a target="_blank" rel="noopener" href="https://vchao.blog.csdn.net/article/details/80787263">手把手带你撸一个校园APP（一）：项目简介</a></li>
<li><a target="_blank" rel="noopener" href="https://vchao.blog.csdn.net/article/details/81456617">手把手带你撸一个校园APP（二）：应用启动和欢迎页面</a></li>
<li><a target="_blank" rel="noopener" href="https://vchao.blog.csdn.net/article/details/81837608">手把手带你撸一个校园APP（三）：用户模块（登录注册等）</a></li>
<li><a target="_blank" rel="noopener" href="https://blog.csdn.net/zheng_weichao/article/details/104209803">手把手带你撸一个校园APP（四）：APP框架及功能设计</a></li>
<li><a href="">手把手带你撸一个校园APP（五）：新闻页面中心模块</a></li>
<li>手把手带你撸一个校园APP（六）：失物招领&amp;二手交易模块</li>
<li>手把手带你撸一个校园APP（七）：图说校园模块</li>
<li>手把手带你撸一个校园APP（八）：校园通讯录模块</li>
<li>手把手带你撸一个校园APP（九）：课程表模块（模拟登陆爬取教务处课程信息）</li>
<li>手把手带你撸一个校园APP（十）：APP通用模块（更新，意见反馈等）</li>
</ol>
<h2 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h2><p>校园的信息量非常庞大，本项目依据校园生活，打造基于 Android 平台的校园信息聚合平台，对校园用户提供信息服务，对校外用户展示校园文化，主要实现了校园新闻、课表查询、失物招领、二手交易、社团活动、网址导航等功能。</p>
<h2 id="PPT介绍"><a href="#PPT介绍" class="headerlink" title="PPT介绍"></a>PPT介绍</h2><p>一时想不起怎么描述才好，就先把PPT截一部分放出来吧。<br><img src="https://img-blog.csdn.net/20180623224203168?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poZW5nX3dlaWNoYW8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70" alt="这里写图片描述"><br>    <img src="https://img-blog.csdn.net/20180623224954867?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poZW5nX3dlaWNoYW8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70" alt=" "><br><img src="https://img-blog.csdn.net/20180623225436229?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poZW5nX3dlaWNoYW8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70" alt="这里写图片描述"><br><img src="https://img-blog.csdn.net/20180623225600137?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poZW5nX3dlaWNoYW8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70" alt="这里写图片描述"><br><img src="https://img-blog.csdn.net/20180623225715160?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poZW5nX3dlaWNoYW8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70" alt="这里写图片描述"><br><img src="https://img-blog.csdn.net/20180623225819560?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poZW5nX3dlaWNoYW8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70" alt="这里写图片描述"><br><img src="https://img-blog.csdn.net/20180623230046979?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poZW5nX3dlaWNoYW8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70" alt="这里写图片描述"><img src="https://img-blog.csdn.net/20180623230259792?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poZW5nX3dlaWNoYW8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70" alt="这里写图片描述"><br><img src="https://img-blog.csdn.net/20180623225947444?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poZW5nX3dlaWNoYW8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70" alt="这里写图片描述"><br><img src="https://img-blog.csdn.net/20180623230356944?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poZW5nX3dlaWNoYW8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70" alt="这里写图片描述"></p>
<p><img src="https://img-blog.csdn.net/20180623230530528?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poZW5nX3dlaWNoYW8=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70" alt="这里写图片描述"></p>
<h2 id="然后"><a href="#然后" class="headerlink" title="然后"></a>然后</h2><p>相信大家已经对这个项目的功能有了一个大致的了解，那之后的几篇文章会对这些功能进行一一实现。</p>
<h2 id="参考内容："><a href="#参考内容：" class="headerlink" title="参考内容："></a>参考内容：</h2><p>太多了，写到哪一部分的时候，我再整理那一部分的吧，届时再来补充。</p>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://vchao.top/2018/04/12/%E6%89%8B%E6%8A%8A%E6%89%8B%E5%B8%A6%E4%BD%A0%E6%92%B8%E4%B8%80%E4%B8%AA%E6%A0%A1%E5%9B%ADAPP%EF%BC%88%E4%B8%83%EF%BC%89%EF%BC%9A%E6%A0%A1%E5%9B%AD%E6%96%87%E5%8C%96%E6%A8%A1%E5%9D%97%EF%BC%88%E7%A4%BE%E5%9B%A2%E6%B4%BB%E5%8A%A8&%E8%A1%A8%E7%99%BD%E5%A2%99&%E5%9B%BE%E8%AF%B4%E6%A0%A1%E5%9B%AD%EF%BC%89/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="vchao">
      <meta itemprop="description" content="怀揣好奇，梦想改变世界的菜鸟极客">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="乘风破浪">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/2018/04/12/%E6%89%8B%E6%8A%8A%E6%89%8B%E5%B8%A6%E4%BD%A0%E6%92%B8%E4%B8%80%E4%B8%AA%E6%A0%A1%E5%9B%ADAPP%EF%BC%88%E4%B8%83%EF%BC%89%EF%BC%9A%E6%A0%A1%E5%9B%AD%E6%96%87%E5%8C%96%E6%A8%A1%E5%9D%97%EF%BC%88%E7%A4%BE%E5%9B%A2%E6%B4%BB%E5%8A%A8&%E8%A1%A8%E7%99%BD%E5%A2%99&%E5%9B%BE%E8%AF%B4%E6%A0%A1%E5%9B%AD%EF%BC%89/" class="post-title-link" itemprop="url">手把手带你撸一个校园APP（七）：校园文化模块（社团活动&表白墙&图说校园）</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2018-04-12 17:51:40" itemprop="dateCreated datePublished" datetime="2018-04-12T17:51:40+08:00">2018-04-12</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="far fa-calendar-check"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2021-08-25 22:37:20" itemprop="dateModified" datetime="2021-08-25T22:37:20+08:00">2021-08-25</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Android/" itemprop="url" rel="index"><span itemprop="name">Android</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>校园文化是以学生为主体，以课外文化活动为主要内容，校园文化建设是以学生为主体，校园为主要空间，涵盖院校领导、教职工在内，以校园精神为主要特征的一种群体文化。<br>校园app，作为学校对外展示校园文化的一个窗口，这一模块的功能也必不可少。科师有约 将这一模块分为 【表白墙 &amp; 图说校园 &amp; 社团活动】 三方面来进行实现。</p>
<blockquote>
<p>在这里附一下【河北科技师范学院】校训： 敏学、修身、乐业、创新</p>
</blockquote>
<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><h4 id="系列文章"><a href="#系列文章" class="headerlink" title="系列文章"></a>系列文章</h4><p>Github地址： <a target="_blank" rel="noopener" href="https://github.com/zhengweichao/Hevttc">科师有约校园APP</a></p>
<ol>
<li><a target="_blank" rel="noopener" href="https://vchao.blog.csdn.net/article/details/80787263">手把手带你撸一个校园APP（一）：项目简介</a></li>
<li><a target="_blank" rel="noopener" href="https://vchao.blog.csdn.net/article/details/81456617">手把手带你撸一个校园APP（二）：应用启动和欢迎页面</a></li>
<li><a target="_blank" rel="noopener" href="https://vchao.blog.csdn.net/article/details/81837608">手把手带你撸一个校园APP（三）：用户模块（登录注册等）</a></li>
<li><a target="_blank" rel="noopener" href="https://blog.csdn.net/zheng_weichao/article/details/104209803">手把手带你撸一个校园APP（四）：APP框架及功能设计</a></li>
<li><a target="_blank" rel="noopener" href="https://blog.csdn.net/zheng_weichao/article/details/104227390">手把手带你撸一个校园APP（五）：新闻页面中心模块</a></li>
<li><a target="_blank" rel="noopener" href="https://vchao.blog.csdn.net/article/details/104245390">手把手带你撸一个校园APP（六）：失物招领&amp;二手交易模块</a></li>
<li><strong>手把手带你撸一个校园APP（七）：校园文化模块（社团活动&amp;表白墙&amp;图说校园）</strong></li>
<li><a href="">手把手带你撸一个校园APP（八）：校园通讯录模块</a></li>
<li>手把手带你撸一个校园APP（九）：课程表模块（模拟登陆爬取教务处课程信息）</li>
<li>手把手带你撸一个校园APP（十）：APP通用模块（更新，意见反馈等）</li>
</ol>
<h2 id="社团组织"><a href="#社团组织" class="headerlink" title="社团组织"></a>社团组织</h2><p>社团活动是校园文化的重要载体，也是学生愉悦身心、拓宽兴趣、开阔视野的主要阵地。<br>丰富多彩的社团活动，能提升学生能力，培养兴趣爱好，激发学生寻找个人特色与才能。每个学校的校园文化也多由此体现。因此设置这个模块，用以展示校园的组织社团等，也为各组织社团提供一种新的线上宣传途径。</p>
<h3 id="实现效果"><a href="#实现效果" class="headerlink" title="实现效果"></a>实现效果</h3><p><img src="https://img-blog.csdnimg.cn/20200213205532771.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poZW5nX3dlaWNoYW8=,size_16,color_FFFFFF,t_70" alt="科师有约社团组织页面"></p>
<h3 id="实现"><a href="#实现" class="headerlink" title="实现"></a>实现</h3><p><strong>数据库</strong><br>| 字段名| 描述 |类型 |是否主键|<br>|—————|————-|————–|——|<br>|objectId     |  唯一标识  |  String     |   是 |<br>|title           | 标题       |  String      |   -  |<br>|description |  描述      |  Number  |  -   |<br>|pic              | 图片       |   String    |  -   |<br>|time           | 发布时间 |  Date       |   -  |</p>
<p><strong>安卓代码</strong><br>查询列表数据，并展示</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">mAdapter = <span class="keyword">new</span> GeneralAdapter();</span><br><span class="line">teamBeen = <span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">rvTeam.setLayoutManager(<span class="keyword">new</span> LinearLayoutManager(TeamActivity.<span class="keyword">this</span>));</span><br><span class="line">BmobQuery&lt;TeamBean&gt; query = <span class="keyword">new</span> BmobQuery&lt;TeamBean&gt;();</span><br><span class="line">query.order(<span class="string">&quot;-time&quot;</span>);</span><br><span class="line">query.setLimit(<span class="number">15</span>);</span><br><span class="line">query.findObjects(<span class="keyword">new</span> FindListener&lt;TeamBean&gt;() &#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">done</span><span class="params">(List&lt;TeamBean&gt; object, BmobException e)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (e == <span class="keyword">null</span>) &#123;</span><br><span class="line">            LogUtils.e(<span class="string">&quot;查询成功：共&quot;</span> + object.size() + <span class="string">&quot;条数据。&quot;</span>);</span><br><span class="line">            teamBeen.addAll(object);</span><br><span class="line">            mAdapter.setData(teamBeen);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            LogUtils.e(<span class="string">&quot;失败：&quot;</span> + e.getMessage() + <span class="string">&quot;,&quot;</span> + e.getErrorCode());</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;);</span><br><span class="line">rvTeam.setAdapter(mAdapter);</span><br></pre></td></tr></table></figure>

<h2 id="表白墙"><a href="#表白墙" class="headerlink" title="表白墙"></a>表白墙</h2><p>近年来，表白墙作为大学校园一种新的社交平台迅速崛起，不仅流行范围广、传播速度快，而且显得异常活跃。这种别具一格的表达方式，由于具有鲜明的时代特点和浓厚的感情色彩，深受大学生的青睐。</p>
<h3 id="效果"><a href="#效果" class="headerlink" title="效果"></a>效果</h3><p>表白墙及发布页面如下：<br><img src="https://img-blog.csdnimg.cn/20200213203006251.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poZW5nX3dlaWNoYW8=,size_18,color_FFFFFF,t_70" alt="科师有约表白墙"></p>
<blockquote>
<p>本人实在没有美术与设计功底，审美也常年掉线。还望勿笑~~</p>
</blockquote>
<h3 id="分析"><a href="#分析" class="headerlink" title="分析"></a>分析</h3><p>从代码层面来分析的话，其实就是数据的发布与查询操作。<br>这部分代码重复性较高，此处就不再赘述了。着重讲下表白信的背景图片【9-patch 图片】。</p>
<h3 id="9-patch-图片"><a href="#9-patch-图片" class="headerlink" title="9-patch 图片"></a>9-patch 图片</h3><p>9-patch 图片常叫做 .9图片。因为文件的后缀名是 .9.png 。<br>是一个指定一些区域可拉伸，另外一些区域不拉伸的位图，同时还可以指定显示内容的区域。在Android开发中，经常使用到.9图片，比如聊天页的消息背景等，以避免因内容导致位图变形。<br>给一个对比图来感受一下，使用和不使用的区别（左：不使用，右：使用）：<br><img src="https://img-blog.csdnimg.cn/20200214153350437.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poZW5nX3dlaWNoYW8=,size_16,color_FFFFFF,t_70" alt="9-patch图片"><br>可以看到，使用普通图片的话，变形会很严重，而使用9patch则会好很多。<br><strong>如何制作9patch图片</strong><br>制作.9图片有很多种方法，最方便快捷的莫过于在Android Studio中进行制作。具体步骤如下：</p>
<p>step1. 准备png图片，需要至少预留1像素的透明区域，然后放到项目drawable或mipmap文件中；<br>step2. 选中该文件，右键选择 “Create 9-Patch file …”，之后drawable 文件夹下回出现同名的 .9.png 图片；<br>step3.  绘制可拉伸区域（在顶部以及左侧划线表示，绘制页面如下图所示，右侧可预览拉伸后的效果）；<br>step4.  和其它图片一样正常使用即可。<br><img src="https://img-blog.csdnimg.cn/20200214155401850.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poZW5nX3dlaWNoYW8=,size_16,color_FFFFFF,t_70" alt="制作9-Patch图片"></p>
<h2 id="图说校园"><a href="#图说校园" class="headerlink" title="图说校园"></a>图说校园</h2><h3 id="效果-1"><a href="#效果-1" class="headerlink" title="效果"></a>效果</h3><p><img src="https://img-blog.csdnimg.cn/20200214103156383.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3poZW5nX3dlaWNoYW8=,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p>
<h3 id="分析-1"><a href="#分析-1" class="headerlink" title="分析"></a>分析</h3><p>这一部分逻辑比较简单，同样是请求数据列表然后展示。<br>不同的是，列表采用了瀑布流的形式展示，其实 RecycleView 可以轻易实现这种效果。<br>数据请求部分代码重复性较高，在此就不再赘述了。这里着重讲跳转页面时的转场动画【共享元素】的实现。<br><strong>共享元素(Shared Element)</strong><br>共享元素属于 Material Design， 为场景切换提供了非常优雅的视觉效果，在进入和退出页面，元素共享页面的时候可以添加想要的效果，能给人元素在运动的感觉。Gif 图如下：<br><img src="https://img-blog.csdnimg.cn/20200214142830872.gif" alt="图说校园共享元素"></p>
<h3 id="实现-1"><a href="#实现-1" class="headerlink" title="实现"></a>实现</h3><h4 id="数据库"><a href="#数据库" class="headerlink" title="数据库"></a>数据库</h4><p>数据库字段设计如下：</p>
<table>
<thead>
<tr>
<th>字段名</th>
<th>描述</th>
<th>类型</th>
<th>是否主键</th>
</tr>
</thead>
<tbody><tr>
<td>objectId</td>
<td>id</td>
<td>String</td>
<td>是</td>
</tr>
<tr>
<td>name</td>
<td>标题</td>
<td>String</td>
<td>-</td>
</tr>
<tr>
<td>description</td>
<td>描述</td>
<td>Number</td>
<td>-</td>
</tr>
<tr>
<td>pic</td>
<td>图片</td>
<td>String</td>
<td>-</td>
</tr>
<tr>
<td>createdAt</td>
<td>发布时间</td>
<td>Date</td>
<td>-</td>
</tr>
</tbody></table>
<p>查询列表等数据请求操作部分代码重复性较高，可参考之前文件代码。在此就不再赘述了。</p>
<h4 id="共享元素"><a href="#共享元素" class="headerlink" title="共享元素"></a>共享元素</h4><p>Step1:</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">style</span> <span class="attr">name</span>=<span class="string">&quot;AppTheme&quot;</span> <span class="attr">parent</span>=<span class="string">&quot;Theme.AppCompat.Light&quot;</span>&gt;</span><span class="xml"></span></span><br><span class="line"><span class="xml">       <span class="tag">&lt;<span class="name">item</span> <span class="attr">name</span>=<span class="string">&quot;android:windowContentTransitions&quot;</span>&gt;</span>true<span class="tag">&lt;/<span class="name">item</span>&gt;</span></span></span><br><span class="line"><span class="xml"></span><span class="tag">&lt;/<span class="name">style</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>Step2:<br>为共享元素设置 transtionName，两个界面都需要要添加，用以标识哪两个元素共享。</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--已省略其它属性--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">ImageView</span></span></span><br><span class="line"><span class="tag">    <span class="attr">android:layout_width</span>=<span class="string">&quot;274dp&quot;</span></span></span><br><span class="line"><span class="tag">    <span class="attr">android:layout_height</span>=<span class="string">&quot;307dp&quot;</span></span></span><br><span class="line"><span class="tag">    <span class="attr">android:transitionName</span>=<span class="string">&quot;shareView&quot;</span> /&gt;</span></span><br></pre></td></tr></table></figure>
<p>当然也可以在代码中设置：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">imageView.setTransitionName(<span class="string">&quot;shareView&quot;</span>);</span><br></pre></td></tr></table></figure>
<p>Step3:<br>设置好以上的参数后，就可以通过跳转来添加相应的动画了。需要用到 ActivityOptionsCompat 的 <strong>makeSceneTransitionAnimation</strong> 函数。代码如下：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Intent i = <span class="keyword">new</span> Intent(mContext, PicDetailActivity.class);</span><br><span class="line">ActivityOptionsCompat optionsCompat = </span><br><span class="line">ActivityOptionsCompat.makeSceneTransitionAnimation(mContext, holder.image, <span class="string">&quot;shareView&quot;</span>);</span><br><span class="line">startActivity(i,optionsCompat.toBundle());</span><br></pre></td></tr></table></figure>
<p>设置多个元素共享的代码如下:</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">Intent i = <span class="keyword">new</span> Intent(mContext, PicDetailActivity.class);</span><br><span class="line">Pair&lt;View, String&gt; pair = <span class="keyword">new</span> Pair&lt;View, String&gt;(holder.image,<span class="string">&quot;shareView&quot;</span>);</span><br><span class="line">Pair&lt;View,String&gt; pairText = <span class="keyword">new</span> Pair&lt;View, String&gt;(holder.text,<span class="string">&quot;text&quot;</span>);</span><br><span class="line">ActivityOptionsCompat optionsCompat = </span><br><span class="line">ActivityOptionsCompat.makeSceneTransitionAnimation(mContext, pair,pairText);</span><br><span class="line">startActivity(i,optionsCompat.toBundle());</span><br></pre></td></tr></table></figure>



<hr>
<p>至此，本文内容全部完毕，项目中内容均为简易实现，深究的话，可以优化的细节极多，然而作者可能并没有更大的精力去全部完善。此项目也权当抛砖引玉之用，望以后可以有学弟学妹做出真正的产品。<br>另外，项目中大量依赖或采用了第三方项目的代码。在此向各位有分享精神的大佬们致敬！</p>
<p>如果本文对你有所帮助，还望可以随手赏一个点赞哈 ~ ~</p>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://vchao.top/2018/04/12/%E6%89%8B%E6%8A%8A%E6%89%8B%E5%B8%A6%E4%BD%A0%E6%92%B8%E4%B8%80%E4%B8%AA%E6%A0%A1%E5%9B%ADAPP%EF%BC%88%E4%B8%89%EF%BC%89%EF%BC%9A%E7%94%A8%E6%88%B7%E6%A8%A1%E5%9D%97%EF%BC%88%E7%99%BB%E5%BD%95%E6%B3%A8%E5%86%8C%E7%AD%89%EF%BC%89/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="vchao">
      <meta itemprop="description" content="怀揣好奇，梦想改变世界的菜鸟极客">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="乘风破浪">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/2018/04/12/%E6%89%8B%E6%8A%8A%E6%89%8B%E5%B8%A6%E4%BD%A0%E6%92%B8%E4%B8%80%E4%B8%AA%E6%A0%A1%E5%9B%ADAPP%EF%BC%88%E4%B8%89%EF%BC%89%EF%BC%9A%E7%94%A8%E6%88%B7%E6%A8%A1%E5%9D%97%EF%BC%88%E7%99%BB%E5%BD%95%E6%B3%A8%E5%86%8C%E7%AD%89%EF%BC%89/" class="post-title-link" itemprop="url">手把手带你撸一个校园APP（三）：用户模块（登录注册等）</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2018-04-12 17:51:40" itemprop="dateCreated datePublished" datetime="2018-04-12T17:51:40+08:00">2018-04-12</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="far fa-calendar-check"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2021-08-25 22:37:20" itemprop="dateModified" datetime="2021-08-25T22:37:20+08:00">2021-08-25</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Android/" itemprop="url" rel="index"><span itemprop="name">Android</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <blockquote>
<p>之前打算写这一整个系列，但是技术有限，怕写出来错误太多误人子弟。就一直拖着没做。今年疫情嚣张，倒也抽出了时间整理下这部分。权当抛砖引玉之用，如有错误，还望不吝赐教。<br>中国加油！武汉加油！希望疫情早日过去。</p>
</blockquote>
<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>登录注册应该是安卓开发中最基础也最通用的功能了。本文就通过这部分来带领大家熟悉一下Bmob的使用。</p>
<p>本人能力有限，很多地方也描述不清。大家可自行查看Bmob开发文档。（<a target="_blank" rel="noopener" href="http://doc.bmob.cn/data/android/develop_doc/%EF%BC%89">http://doc.bmob.cn/data/android/develop_doc/）</a></p>
<p><a target="_blank" rel="noopener" href="https://vchao.blog.csdn.net/article/details/80787263">手把手带你撸一个校园APP（一）：项目简介</a><br><a target="_blank" rel="noopener" href="https://vchao.blog.csdn.net/article/details/81456617">手把手带你撸一个校园APP（二）：应用启动和欢迎页面</a></p>
<h2 id="后台"><a href="#后台" class="headerlink" title="后台"></a>后台</h2><p>为了更加高效的开发，校园APP并没有自己编写后台代码，而是采用的Bmob后端云提供的数据库功能。其实如果想自己写后台的话也可以，原理大致相同。</p>
<h2 id="数据库设计"><a href="#数据库设计" class="headerlink" title="数据库设计"></a>数据库设计</h2><p>因为我们要用的是Bmob提供的云数据库，所以就得先了解下bmob数据库的规则。</p>
<blockquote>
<p>与其它数据库不同，Bmob在数据存储与数据类型方面都有一套自己的规范。从数据存储方面来说，所有存储数据均会默认增加唯一标识objectId，创建时间createdAt等常用属性，在设计数据格式时，无需再重复这些属性。从数据类型方面来说，Bmob支持的数据类型更为广泛，除了String、Float、Boolean等基础类型之外，同时也支持日期格式类型BmobDate和文件格式类型BmobFile等特有的数据类型。</p>
</blockquote>
<p>总结一下就是：</p>
<ul>
<li>默认增加objectId,createdAt,updateAt 等字段（每个表的主键，还有创建时间等无需额外处理了）</li>
<li>支持文件存储（一些图片可以直接存起来）</li>
</ul>
<p>回到我们的需求，整理一下，不难发现用户信息表需要以下字段：</p>
<table>
<thead>
<tr>
<th>字段名</th>
<th>描述</th>
<th>类型</th>
<th>主键</th>
</tr>
</thead>
<tbody><tr>
<td>objectId</td>
<td>用户id</td>
<td>String</td>
<td>是</td>
</tr>
<tr>
<td>username</td>
<td>用户名</td>
<td>String</td>
<td></td>
</tr>
<tr>
<td>password</td>
<td>密码</td>
<td>String</td>
<td></td>
</tr>
<tr>
<td>mobilePhoneNumber</td>
<td>手机号</td>
<td>String</td>
<td></td>
</tr>
<tr>
<td>clazz</td>
<td>班级</td>
<td>String</td>
<td></td>
</tr>
<tr>
<td>sex</td>
<td>性别</td>
<td>Boolean</td>
<td></td>
</tr>
<tr>
<td>stuno</td>
<td>学号</td>
<td>String</td>
<td></td>
</tr>
<tr>
<td>yuan</td>
<td>院系</td>
<td>String</td>
<td></td>
</tr>
</tbody></table>
<p>更贴心的是，Bmob中提供了默认的User表。上面的很多字段已经包含在内了。直接在控制台_User 表中补充其它字段即可。</p>
<h2 id="安卓端程序"><a href="#安卓端程序" class="headerlink" title="安卓端程序"></a>安卓端程序</h2><h2 id="布局"><a href="#布局" class="headerlink" title="布局"></a>布局</h2><p>页面布局比较简单，有点基础的基本都可以看出来，这里遵循Material Design风格，控件使用了 TextInputLayout 。</p>
<h3 id="TextInputLayout"><a href="#TextInputLayout" class="headerlink" title="TextInputLayout"></a>TextInputLayout</h3><p>TextInputLayout 主要是作为 EditText 的容器，从而为 EditText 生成一个浮动的 Label，当用户点击 EditText 的时候，EditText 中的 hint 字符串会自动移到 EditText 的左上角。</p>
<p><strong>为什么使用TextInputLayout</strong> </p>
<ol>
<li>方便控制密码输入框内容的显示与隐藏</li>
<li>浮动提示语（Metrial Design风格）</li>
</ol>
<p>当然了，不使用也没有什么影响。</p>
<p><strong>基本用法：</strong><br>xml布局</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">android.support.design.widget.TextInputLayout</span></span></span><br><span class="line"><span class="tag">    <span class="attr">android:layout_width</span>=<span class="string">&quot;match_parent&quot;</span></span></span><br><span class="line"><span class="tag">    <span class="attr">android:layout_height</span>=<span class="string">&quot;wrap_content&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">EditText</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:layout_width</span>=<span class="string">&quot;match_parent&quot;</span></span></span><br><span class="line"><span class="tag">        <span class="attr">android:layout_height</span>=<span class="string">&quot;wrap_content&quot;</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">android.support.design.widget.TextInputLayout</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p><strong>扩展：TextInputLayout 常用属性及方法：</strong></p>
<table>
<thead>
<tr>
<th>属性名</th>
<th>对应方法</th>
<th>作用</th>
</tr>
</thead>
<tbody><tr>
<td>app:hint</td>
<td>setHint(CharSequence)</td>
<td>设置浮动提示语</td>
</tr>
<tr>
<td>app:hintEnabled</td>
<td>setHintEnabled(boolean)</td>
<td>设置是否开启浮动功能</td>
</tr>
<tr>
<td>app:hintAnimationEnabled</td>
<td>setHintAnimationEnabled(boolean)</td>
<td>设置是否开启浮动提示动画</td>
</tr>
<tr>
<td>null</td>
<td>setError</td>
<td>设置错误提示</td>
</tr>
<tr>
<td>app:errorEnabled</td>
<td>setErrorEnabled(boolean)</td>
<td>设置是否开启错误提示</td>
</tr>
<tr>
<td>app:counterEnabled</td>
<td>setCounterEnabled(boolean)</td>
<td>设置是否开启计数器</td>
</tr>
<tr>
<td>app:counterMaxLength</td>
<td>setCounterMaxLength(int)</td>
<td>设置计数器的最大长度（超过并不影响输入）</td>
</tr>
<tr>
<td>app:passwordToggleEnabled</td>
<td>setPasswordVisibilityToggleEnabled(boolean)</td>
<td>设置是否开启密码可见开关(EditText必须为password类型才起作用)</td>
</tr>
<tr>
<td>app:passwordToggleDrawable</td>
<td>setPasswordVisibilityToggleDrawable(Drawable)</td>
<td>设置密码可见开关的图标</td>
</tr>
</tbody></table>
<h2 id="java-逻辑"><a href="#java-逻辑" class="headerlink" title="java 逻辑"></a>java 逻辑</h2><p>该部分基本按照bmob官方文档来操作。<a target="_blank" rel="noopener" href="http://doc.bmob.cn/data/android/develop_doc/#2">Bmob用户系统</a></p>
<ol>
<li>创建表对应的bean类。User表需要继承自BmobUser，其中已封装用户名，密码等属性，以及登录，注册等方法。</li>
</ol>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MyUser</span> <span class="keyword">extends</span> <span class="title">BmobUser</span> </span>&#123;</span><br><span class="line">    <span class="keyword">private</span> String stuno;</span><br><span class="line">    <span class="keyword">private</span> String sex;</span><br><span class="line">    <span class="keyword">private</span> String yuan;</span><br><span class="line">    <span class="keyword">private</span> String clazz;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 自行实现get set方法...</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ol start="2">
<li>登录，BmobUser中封装了多种登录方法，我们这里采用账号密码登录的方式。</li>
</ol>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 手机号登录</span></span><br><span class="line">BmobUser.loginByAccount(username, password, <span class="keyword">new</span> LogInListener&lt;MyUser&gt;() &#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">done</span><span class="params">(MyUser user, BmobException e)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (user != <span class="keyword">null</span>) &#123;</span><br><span class="line">            <span class="comment">// 登录成功</span></span><br><span class="line">            onLoginSuccess();</span><br><span class="line">            progressDialog.dismiss();</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="comment">// 登录失败</span></span><br><span class="line">            onLoginFailed();</span><br><span class="line">            progressDialog.dismiss();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<ol start="3">
<li>注册。Bmob中也封装了很多注册方法。账号密码注册比较简单。当然也可以做成用验证码注册的，不过需要提前充值短信条数。</li>
</ol>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">final</span> User user = <span class="keyword">new</span> User();</span><br><span class="line">user.setUsername(<span class="string">&quot;username&quot;</span>);</span><br><span class="line">user.setPassword(<span class="string">&quot;password&quot;</span>);</span><br><span class="line">user.signUp(<span class="keyword">new</span> SaveListener&lt;User&gt;() &#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">done</span><span class="params">(User user, BmobException e)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (e == <span class="keyword">null</span>) &#123;</span><br><span class="line">            <span class="comment">// 注册成功</span></span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="comment">// 注册失败</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<ol start="4">
<li>获取当前登录的用户以及用户属性。</li>
</ol>
<blockquote>
<p>获取缓存的用户信息，缓存的有效期为1年。</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (BmobUser.isLogin()) &#123;</span><br><span class="line">    <span class="comment">// 获取缓存用户对象</span></span><br><span class="line">    MyUser user = BmobUser.getCurrentUser(MyUser.class);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ol start="5">
<li>退出登录</li>
</ol>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//清除缓存用户对象，退出登录</span></span><br><span class="line">BmobUser.logOut();</span><br></pre></td></tr></table></figure>

<h2 id="补充优化"><a href="#补充优化" class="headerlink" title="补充优化"></a>补充优化</h2><ul>
<li>凡是输入框都应该根据实际情况做一些限制，比如输入类型，输入长度，以此来减少用户恶意操作。</li>
<li>登录注册页面来回跳转后，应该对返回键做相应处理，防止返回时再次跳转。</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 重写返回键的返回方法</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onBackPressed</span><span class="params">()</span> </span>&#123;</span><br><span class="line">    <span class="comment">// Disable going back to the ReviewTestActivity</span></span><br><span class="line">    moveTaskToBack(<span class="keyword">true</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ul>
<li>页面跳转时，可以设置相应的跳转动画，以此优化用户体验。</li>
</ul>
<p>java代码</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">Intent intent = <span class="keyword">new</span> Intent(getApplicationContext(), SignupActivity.class);</span><br><span class="line">startActivityForResult(intent, REQUEST_SIGNUP);</span><br><span class="line">finish();</span><br><span class="line"><span class="comment">//动画效果</span></span><br><span class="line">overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);</span><br></pre></td></tr></table></figure>

<p>动画<br>push_left_in.xml</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">set</span> <span class="attr">xmlns:android</span>=<span class="string">&quot;http://schemas.android.com/apk/res/android&quot;</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">translate</span></span></span><br><span class="line"><span class="tag">		<span class="attr">android:duration</span>=<span class="string">&quot;500&quot;</span></span></span><br><span class="line"><span class="tag">		<span class="attr">android:fromXDelta</span>=<span class="string">&quot;100%p&quot;</span></span></span><br><span class="line"><span class="tag">		<span class="attr">android:toXDelta</span>=<span class="string">&quot;0&quot;</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">set</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>push_left_out.xml</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">set</span> <span class="attr">xmlns:android</span>=<span class="string">&quot;http://schemas.android.com/apk/res/android&quot;</span>&gt;</span></span><br><span class="line">	<span class="tag">&lt;<span class="name">translate</span></span></span><br><span class="line"><span class="tag">		<span class="attr">android:duration</span>=<span class="string">&quot;500&quot;</span></span></span><br><span class="line"><span class="tag">		<span class="attr">android:fromXDelta</span>=<span class="string">&quot;0&quot;</span></span></span><br><span class="line"><span class="tag">		<span class="attr">android:toXDelta</span>=<span class="string">&quot;-100%p&quot;</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">set</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p>如果本文对你有所帮助，还望可以随手赏一个点赞哈 ~ ~</p>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://vchao.top/2018/04/03/%E5%AE%89%E5%8D%93%E5%9F%BA%E7%A1%80%E6%9D%83%E9%99%90%E6%80%BB%E7%BB%93/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="vchao">
      <meta itemprop="description" content="怀揣好奇，梦想改变世界的菜鸟极客">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="乘风破浪">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/2018/04/03/%E5%AE%89%E5%8D%93%E5%9F%BA%E7%A1%80%E6%9D%83%E9%99%90%E6%80%BB%E7%BB%93/" class="post-title-link" itemprop="url">安卓基础权限总结</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2018-04-03 10:30:56" itemprop="dateCreated datePublished" datetime="2018-04-03T10:30:56+08:00">2018-04-03</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="far fa-calendar-check"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2021-08-25 22:37:20" itemprop="dateModified" datetime="2021-08-25T22:37:20+08:00">2021-08-25</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Android/" itemprop="url" rel="index"><span itemprop="name">Android</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>﻿&gt; 安卓的权限特别多，这里简单总结一下，以作备忘。</p>
<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>在安卓6.0之前，所有权限只要声明即可。<br>从安卓6.0开始，权限就进行了分级，高危权限需要在代码中进行动态申请。<br>除了可以代码中申请的权限外，还有一些权限需要用户手动开启。例如悬浮窗权限，安装未知来源应用权限。<br>此外还有一个方法，可以免除权限的申请，就是开启设备管理器。</p>
<h2 id="动态权限"><a href="#动态权限" class="headerlink" title="动态权限"></a>动态权限</h2><p>动态权限的申请在Activity和fragment的操作不一样。需要注意以下。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 1.Activtity 申请权限</span></span><br><span class="line"><span class="keyword">if</span>(ContextCompat.checkSelfPermission(XXX.<span class="keyword">this</span>,Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)&#123;</span><br><span class="line">     <span class="comment">//没有权限</span></span><br><span class="line">     ActivityCompat.requestPermissions(XXX.<span class="keyword">this</span>,<span class="keyword">new</span> String[]&#123;</span><br><span class="line">                                    Manifest.permission.WRITE_EXTERNAL_STORAGE&#125;,<span class="number">1</span>);</span><br><span class="line">&#125;<span class="keyword">else</span> &#123;</span><br><span class="line">     <span class="comment">// 有权限 ...</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 2. Fragment 申请权限</span></span><br><span class="line"><span class="keyword">if</span>(ContextCompat.checkSelfPermission(getActivity(),Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)&#123;</span><br><span class="line">		<span class="comment">//没有权限</span></span><br><span class="line">          requestPermissions(<span class="keyword">new</span> String[]&#123;</span><br><span class="line">                                    Manifest.permission.WRITE_EXTERNAL_STORAGE&#125;,<span class="number">1</span>);</span><br><span class="line">&#125;<span class="keyword">else</span> &#123;</span><br><span class="line">       <span class="comment">// 有权限 ...</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 3. 权限返回</span></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onRequestPermissionsResult</span><span class="params">(<span class="keyword">int</span> requestCode, String[] permissions, <span class="keyword">int</span>[] grantResults)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>.onRequestPermissionsResult(requestCode, permissions, grantResults);</span><br><span class="line">        <span class="keyword">switch</span> (requestCode)&#123;</span><br><span class="line">            <span class="keyword">case</span> <span class="number">1</span>:</span><br><span class="line">                <span class="keyword">if</span>(grantResults.length &gt; <span class="number">0</span> &amp;&amp; grantResults[<span class="number">0</span>] == PackageManager.PERMISSION_GRANTED)&#123;</span><br><span class="line">                    <span class="comment">// 允许了权限 ...</span></span><br><span class="line">                &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">                	<span class="comment">// 拒绝了权限 ...</span></span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>
<p>Fragment中运行时权限的特殊处理<br>在Fragment中申请权限，不要使用ActivityCompat.requestPermissions, 直接使用Fragment的requestPermissions方法，否则会回调到Activity的 onRequestPermissionsResult<br>如果在Fragment中嵌套Fragment，在子Fragment中使用requestPermissions方 法，onRequestPermissionsResult不会回调回来，建议使用 getParentFragment().requestPermissions方法，这个方法会回调到父Fragment中的onRequestPermissionsResult，加入以下代码可以把回调透传到子Fragment</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onRequestPermissionsResult</span><span class="params">(<span class="keyword">int</span> requestCode, String[] permissions, <span class="keyword">int</span>[] grantResults)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">super</span>.onRequestPermissionsResult(requestCode, permissions, grantResults);</span><br><span class="line">        List&lt;Fragment&gt; fragments = getChildFragmentManager().getFragments();</span><br><span class="line">        <span class="keyword">if</span> (fragments != <span class="keyword">null</span>) &#123;</span><br><span class="line">            <span class="keyword">for</span> (Fragment fragment : fragments) &#123;</span><br><span class="line">                <span class="keyword">if</span> (fragment != <span class="keyword">null</span>) &#123;</span><br><span class="line">                  fragment.onRequestPermissionsResult(requestCode,permissions,grantResults);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>

<h2 id="权限列表"><a href="#权限列表" class="headerlink" title="权限列表"></a>权限列表</h2><table>
<thead>
<tr>
<th>权限</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td>android.permission.INTERNET，</td>
<td>访问网络连接，可能产生GPRS流量</td>
</tr>
<tr>
<td>android.permission.CHANGE_WIFI_STATE</td>
<td>Wifi 改变状态</td>
</tr>
<tr>
<td>android.permission.ACCESS_WIFI_STATE</td>
<td>WiFi 状态</td>
</tr>
<tr>
<td>android.permission.ACCESS_NETWORK_STATE</td>
<td>网络状态</td>
</tr>
<tr>
<td>android.permission.CAMERA</td>
<td>相机</td>
</tr>
<tr>
<td>android.permission.RECORD_AUDIO</td>
<td>自动聚焦</td>
</tr>
<tr>
<td>android.permission.WRITE_EXTERNAL_STORAGE</td>
<td>写内存</td>
</tr>
<tr>
<td>android.permission.CWJ_GROUP</td>
<td>底层访问权限，允许CWJ账户组访问底层信息</td>
</tr>
<tr>
<td>android.permission.CELL_PHONE_MASTER_EX</td>
<td>手机优化大师扩展权限</td>
</tr>
<tr>
<td>android.permission.CONTROL_LOCATION_UPDATES</td>
<td>控制定位更新，允许获得移动网络定位信息改变</td>
</tr>
<tr>
<td>android.permission.DELETE_CACHE_FILES</td>
<td>删除缓存文件,允许应用删除缓存文件</td>
</tr>
<tr>
<td>android.permission.DELETE_PACKAGES</td>
<td>允许程序删除应用</td>
</tr>
<tr>
<td>android.permission.DEVICE_POWER</td>
<td>允许访问底层电源管理</td>
</tr>
<tr>
<td>android.permission.DIAGNOSTIC</td>
<td>允许程序到RW到诊断资源</td>
</tr>
<tr>
<td>android.permission.DISABLE_KEYGUARD</td>
<td>允许程序禁用键盘锁</td>
</tr>
<tr>
<td>android.permission.DUMP</td>
<td>允许程序获取系统dump信息从系统服务</td>
</tr>
<tr>
<td>android.permission.EXPAND_STATUS_BAR</td>
<td>允许程序扩展或收缩状态栏</td>
</tr>
<tr>
<td>android.permission.FACTORY_TEST</td>
<td>允许程序运行工厂测试模式</td>
</tr>
<tr>
<td>android.permission.FLASHLIGHT</td>
<td>允许访问闪光灯</td>
</tr>
<tr>
<td>android.permission.FORCE_BACK</td>
<td>允许程序强制使用back后退按键无论Activity是否在顶层</td>
</tr>
<tr>
<td>android.permission.GET_ACCOUNTS</td>
<td>访问GMail账户列表</td>
</tr>
<tr>
<td>android.permission.GET_PACKAGE_SIZE</td>
<td>获取应用的文件大小</td>
</tr>
<tr>
<td>android.permission.GET_TASKS</td>
<td>允许程序获取当前或最近运行的应用</td>
</tr>
<tr>
<td>android.permission.GLOBAL_SEARCH</td>
<td>允许程序使用全局搜索功能</td>
</tr>
<tr>
<td>android.permission.HARDWARE_TEST</td>
<td>访问硬件辅助设备用于硬件测试</td>
</tr>
<tr>
<td>android.permission.INJECT_EVENTS</td>
<td>允许访问本程序的底层事件，获取按键、轨迹球的事件流</td>
</tr>
<tr>
<td>android.permission.INSTALL_LOCATION_PROVIDER</td>
<td>安装定位提供</td>
</tr>
<tr>
<td>android.permission.INSTALL_PACKAGES</td>
<td>允许程序安装应用</td>
</tr>
<tr>
<td>android.permission.INTERNAL_SYSTEM_WINDOW</td>
<td>允许程序打开内部窗口不对第三方应用程序开放此权限</td>
</tr>
<tr>
<td>android.permission.KILL_BACKGROUND_PROCESSES</td>
<td>允许程序调用killBackgroundProcesses(String).方法结束后台进程</td>
</tr>
<tr>
<td>android.permission.MANAGE_ACCOUNTS</td>
<td>允许程序管理AccountManager中的账户列表</td>
</tr>
<tr>
<td>android.permission.MANAGE_APP_TOKENS</td>
<td>管理创建、摧毁、Z轴顺序仅用于系统</td>
</tr>
<tr>
<td>android.permission.MTWEAK_USER</td>
<td>允许mTweak用户访问高级系统权限</td>
</tr>
<tr>
<td>android.permission.MTWEAK_FORUM</td>
<td>允许使用mTweak社区权限</td>
</tr>
<tr>
<td>android.permission.MASTER_CLEAR</td>
<td>允许程序执行软格式化 删除系统配置信息</td>
</tr>
<tr>
<td>android.permission.MODIFY_AUDIO_SETTINGS</td>
<td>修改声音设置信息</td>
</tr>
<tr>
<td>android.permission.MODIFY_PHONE_STATE</td>
<td>修改电话状态,如飞行模式，但不包含替换系统拨号器界面</td>
</tr>
<tr>
<td>android.permission.MOUNT_FORMAT_FILESYSTEMS</td>
<td>格式化可移动文件系统，比如格式化清空SD卡</td>
</tr>
<tr>
<td>android.permission.MOUNT_UNMOUNT_FILESYSTEMS</td>
<td>挂载、反挂载外部文件系统</td>
</tr>
<tr>
<td>android.permission.NFC</td>
<td>允许程序执行NFC近距离通讯操作,用于移动支持</td>
</tr>
<tr>
<td>android.permission.PERSISTENT_ACTIVITY</td>
<td>创建一个永久的Activity该功能标记为将来将被移除</td>
</tr>
<tr>
<td>android.permission.PROCESS_OUTGOING_CALLS</td>
<td>允许程序监视修改或放弃播出电话</td>
</tr>
<tr>
<td>android.permission.READ_CALENDAR</td>
<td>允许程序读取用户的日程信息</td>
</tr>
<tr>
<td>android.permission.READ_CONTACTS</td>
<td>允许应用访问联系人通讯录信息</td>
</tr>
<tr>
<td>android.permission.READ_FRAME_BUFFER</td>
<td>读取帧缓存用于屏幕截图</td>
</tr>
<tr>
<td>com.android.browser.permission.READ_HISTORY_BOOKMARKS</td>
<td>读取浏览器收藏夹和历史记录</td>
</tr>
<tr>
<td>android.permission.READ_INPUT_STATE</td>
<td>读取当前键的输入状态，仅用于系统</td>
</tr>
<tr>
<td>android.permission.READ_LOGS</td>
<td>读取系统底层日志</td>
</tr>
<tr>
<td>android.permission.READ_PHONE_STATE</td>
<td>访问电话状态</td>
</tr>
<tr>
<td>android.permission.READ_SMS</td>
<td>读取短信内容</td>
</tr>
<tr>
<td>android.permission.READ_SYNC_SETTINGS</td>
<td>读取同步设置，读取Google在线同步设置</td>
</tr>
<tr>
<td>android.permission.READ_SYNC_STATS</td>
<td>读取同步状态，获得Google在线同步状态</td>
</tr>
<tr>
<td>android.permission.REBOOT</td>
<td>允许程序重新启动设备</td>
</tr>
<tr>
<td>android.permission.RECEIVE_BOOT_COMPLETED</td>
<td>允许程序开机自动运行</td>
</tr>
<tr>
<td>android.permission.RECEIVE_MMS</td>
<td>接收彩信</td>
</tr>
<tr>
<td>android.permission.RECEIVE_SMS</td>
<td>接收短信</td>
</tr>
<tr>
<td>android.permission.RECEIVE_WAP_PUSH</td>
<td>接收WAP PUSH信息</td>
</tr>
<tr>
<td>android.permission.RECORD_AUDIO</td>
<td>录制声音通过手机或耳机的麦克</td>
</tr>
<tr>
<td>android.permission.REORDER_TASKS</td>
<td>重新排序系统Z轴运行中的任务</td>
</tr>
<tr>
<td>android.permission.RESTART_PACKAGES</td>
<td>结束任务通过restartPackage(String)方法,该方式将在外来放弃</td>
</tr>
<tr>
<td>android.permission.SEND_SMS</td>
<td>发送短信</td>
</tr>
<tr>
<td>android.permission.SET_ACTIVITY_WATCHER</td>
<td>设置Activity观察器一般用于monkey测试</td>
</tr>
<tr>
<td>com.android.alarm.permission.SET_ALARM</td>
<td>设置闹铃提醒</td>
</tr>
<tr>
<td>android.permission.SET_ALWAYS_FINISH</td>
<td>设置程序在后台是否总是退出</td>
</tr>
<tr>
<td>android.permission.SET_ANIMATION_SCALE</td>
<td>设置全局动画缩放</td>
</tr>
<tr>
<td>android.permission.SET_DEBUG_APP</td>
<td>设置调试程序,一般用于开发</td>
</tr>
<tr>
<td>android.permission.SET_ORIENTATION</td>
<td>设置屏幕方向为横屏或标准方式显示,不用于普通应用</td>
</tr>
<tr>
<td>android.permission.SET_PREFERRED_APPLICATIONS</td>
<td>设置应用的参数,已不再工作具体查看addPackageToPreferred(String)介绍</td>
</tr>
<tr>
<td>android.permission.SET_PROCESS_LIMIT</td>
<td>允许程序设置最大的进程数量的限制</td>
</tr>
<tr>
<td>android.permission.SET_TIME</td>
<td>设置系统时间</td>
</tr>
<tr>
<td>android.permission.SET_TIME_ZONE</td>
<td>设置系统时区</td>
</tr>
<tr>
<td>android.permission.SET_WALLPAPER</td>
<td>设置桌面壁纸</td>
</tr>
<tr>
<td>android.permission.SET_WALLPAPER_HINTS</td>
<td>设置壁纸建议</td>
</tr>
<tr>
<td>android.permission.SIGNAL_PERSISTENT_PROCESSES</td>
<td>发送一个永久的进程信号</td>
</tr>
<tr>
<td>android.permission.STATUS_BAR</td>
<td>允许程序打开、关闭、禁用状态栏</td>
</tr>
<tr>
<td>android.permission.SUBSCRIBED_FEEDS_READ</td>
<td>访问订阅信息的数据库</td>
</tr>
<tr>
<td>android.permission.SUBSCRIBED_FEEDS_WRITE</td>
<td>写入或修改订阅内容的数据库</td>
</tr>
<tr>
<td>android.permission.SYSTEM_ALERT_WINDOW</td>
<td>显示系统窗口</td>
</tr>
<tr>
<td>android.permission.UPDATE_DEVICE_STATS</td>
<td>更新设备状态</td>
</tr>
<tr>
<td>android.permission.USE_CREDENTIALS</td>
<td>允许程序请求验证从AccountManager</td>
</tr>
<tr>
<td>android.permission.USE_SIP</td>
<td>允许程序使用SIP视频服务</td>
</tr>
<tr>
<td>android.permission.VIBRATE</td>
<td>允许振动</td>
</tr>
<tr>
<td>android.permission.WAKE_LOCK</td>
<td>允许程序在手机屏幕关闭后后台进程仍然运行</td>
</tr>
<tr>
<td>android.permission.WRITE_APN_SETTINGS</td>
<td>写入网络GPRS接入点设置</td>
</tr>
<tr>
<td>android.permission.WRITE_CALENDAR</td>
<td>写入日程,但不可读取</td>
</tr>
<tr>
<td>android.permission.WRITE_CONTACTS</td>
<td>写入联系人,但不可读取</td>
</tr>
<tr>
<td>android.permission.WRITE_EXTERNAL_STORAGE</td>
<td>允许程序写入外部存储,如SD卡上写文件</td>
</tr>
<tr>
<td>android.permission.WRITE_GSERVICES</td>
<td>允许程序写入Google Map服务数据</td>
</tr>
<tr>
<td>com.android.browser.permission.WRITE_HISTORY_BOOKMARKS</td>
<td>写入浏览器历史记录或收藏夹.但不可读取</td>
</tr>
<tr>
<td>android.permission.WRITE_SECURE_SETTINGS</td>
<td>允许程序读写系统安全敏感的设置项</td>
</tr>
<tr>
<td>android.permission.WRITE_SETTINGS</td>
<td>允许读写系统设置项</td>
</tr>
<tr>
<td>android.permission.WRITE_SMS</td>
<td>允许编写短信</td>
</tr>
<tr>
<td>android.permission.WRITE_SYNC_SETTINGS</td>
<td>写入Google在线同步设置</td>
</tr>
<tr>
<td>android.permission.ACCESS_CHECKIN_PROPERTIES</td>
<td>读取或写入登记check-in数据库属性表的权限</td>
</tr>
<tr>
<td>android.permission.ACCESS_COARSE_LOCATION</td>
<td>通过WiFi或移动基站的方式获取用户错略的经纬度信息，定位精度大概误差在30~1500米</td>
</tr>
<tr>
<td>android.permission.ACCESS_FINE_LOCATION</td>
<td>通过GPS芯片接收卫星的定位信息,定位精度达10米以内</td>
</tr>
<tr>
<td>android.permission.ACCESS_LOCATION_EXTRA_COMMANDS</td>
<td>允许程序访问额外的定位提供者指令</td>
</tr>
<tr>
<td>android.permission.ACCESS_MOCK_LOCATION</td>
<td>获取模拟定位信息，一般用于帮助开发者调试应用</td>
</tr>
<tr>
<td>android.permission.ACCESS_NETWORK_STATE</td>
<td>获取网络信息状态，如当前的网络连接是否有效</td>
</tr>
<tr>
<td>android.permission.ACCESS_SURFACE_FLINGER</td>
<td>Android平台上底层的图形显示支持，一般用于游戏或照相机预览界面和底层模式的屏幕截图</td>
</tr>
<tr>
<td>android.permission.ACCESS_WIFI_STATE</td>
<td>获取当前WiFi接入的状态以及WLAN热点的信息</td>
</tr>
<tr>
<td>android.permission.ACCOUNT_MANAGER</td>
<td>获取账户验证信息主要为GMail账户信息，只有系统级进程才能访问的权限</td>
</tr>
<tr>
<td>android.permission.AUTHENTICATE_ACCOUNTS</td>
<td>允许一个程序通过账户验证方式访问账户管理ACCOUNT_MANAGER相关信息</td>
</tr>
<tr>
<td>android.permission.BATTERY_STATS</td>
<td>获取电池电量统计信息</td>
</tr>
<tr>
<td>android.permission.BIND_APPWIDGET</td>
<td>允许一个程序告诉appWidget服务需要访问小插件的数据库只有非常少的应用才用到此权限</td>
</tr>
<tr>
<td>android.permission.BIND_DEVICE_ADMIN</td>
<td>请求系统管理员接收者receiver，只有系统才能使用</td>
</tr>
<tr>
<td>android.permission.BIND_INPUT_METHOD</td>
<td>请求InputMethodService服务只有系统才能使用</td>
</tr>
<tr>
<td>android.permission.BIND_REMOTEVIEWS</td>
<td>必须通过RemoteViewsService服务来请求，只有系统才能用</td>
</tr>
<tr>
<td>android.permission.BIND_WALLPAPER</td>
<td>必须通过WallpaperService服务来请求，只有系统才能用</td>
</tr>
<tr>
<td>android.permission.BLUETOOTH</td>
<td>允许程序连接配对过的蓝牙设备</td>
</tr>
<tr>
<td>android.permission.BLUETOOTH_ADMIN</td>
<td>允许程序进行发现和配对新的蓝牙设备</td>
</tr>
<tr>
<td>android.permission.BRICK</td>
<td>能够禁用手机，非常危险，顾名思义就是让手机变成砖头</td>
</tr>
<tr>
<td>android.permission.BROADCAST_PACKAGE_REMOVED</td>
<td>当一个应用在删除时触发一个广播</td>
</tr>
<tr>
<td>android.permission.BROADCAST_SMS</td>
<td>当收到短信时触发一个广播</td>
</tr>
<tr>
<td>android.permission.BROADCAST_STICKY</td>
<td>允许一个程序收到广播后快速收到下一个广播</td>
</tr>
<tr>
<td>android.permission.BROADCAST_WAP_PUSH</td>
<td>WAP PUSH服务收到后触发一个广播</td>
</tr>
<tr>
<td>android.permission.CALL_PHONE</td>
<td>允许程序从非系统拨号器里输入电话号码</td>
</tr>
<tr>
<td>android.permission.CALL_PRIVILEGED</td>
<td>允许程序拨打电话，替换系统的拨号器界面</td>
</tr>
<tr>
<td>android.permission.CAMERA</td>
<td>允许访问摄像头进行拍照</td>
</tr>
<tr>
<td>android.permission.CHANGE_COMPONENT_ENABLED_STATE</td>
<td>改变组件是否启用状态</td>
</tr>
<tr>
<td>android.permission.CHANGE_CONFIGURATION</td>
<td>允许当前应用改变配置，如定位</td>
</tr>
<tr>
<td>android.permission.CHANGE_NETWORK_STATE</td>
<td>改变网络状态如是否能联网</td>
</tr>
<tr>
<td>android.permission.CHANGE_WIFI_MULTICAST_STATE</td>
<td>改变WiFi多播状态</td>
</tr>
<tr>
<td>android.permission.CHANGE_WIFI_STATE</td>
<td>改变WiFi状态</td>
</tr>
<tr>
<td>android.permission.CLEAR_APP_CACHE</td>
<td>清除应用缓存</td>
</tr>
<tr>
<td>android.permission.CLEAR_APP_USER_DATA</td>
<td>清除应用的用户数据</td>
</tr>
</tbody></table>
<p>参考：<br><a target="_blank" rel="noopener" href="https://blog.csdn.net/koma025/article/details/52913511">https://blog.csdn.net/koma025/article/details/52913511</a></p>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://vchao.top/2018/03/19/%E5%AE%89%E5%8D%93%EF%BC%9A%E4%BB%8E%E7%BD%91%E9%A1%B5%E5%94%A4%E9%86%92APP/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="vchao">
      <meta itemprop="description" content="怀揣好奇，梦想改变世界的菜鸟极客">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="乘风破浪">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/2018/03/19/%E5%AE%89%E5%8D%93%EF%BC%9A%E4%BB%8E%E7%BD%91%E9%A1%B5%E5%94%A4%E9%86%92APP/" class="post-title-link" itemprop="url">安卓：从网页唤醒APP</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2018-03-19 15:26:00" itemprop="dateCreated datePublished" datetime="2018-03-19T15:26:00+08:00">2018-03-19</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="far fa-calendar-check"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2021-08-25 22:37:20" itemprop="dateModified" datetime="2021-08-25T22:37:20+08:00">2021-08-25</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Android/" itemprop="url" rel="index"><span itemprop="name">Android</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>﻿# 前言</p>
<p>现在都流行立体式的互联网，一般公司都会有自己的APP，网站，微信公众号，小程序等众多流量入口。为了更好的用户体验，也为了提高用户粘度，打通这些程序的入口，使其联动成为一体十分重要，以此达到相互引流的作用。<br>APP和网页之间的联动最为常见。很多网页都有这样的功能：在网页点击某一个按钮，或者跳转到某一网页之后，就会唤醒APP，以此达到联动效果。</p>
<h1 id="分析"><a href="#分析" class="headerlink" title="分析"></a>分析</h1><p>我们都知道各个系统用的开发语言不尽相同，那么这种效果到底是如何做的呢？<br>答案就是……scheme。<br>对应到安卓中就是具体表现为 xml 中的 android:scheme 属性，通过&lt;intent-filter&gt; 设置data，已达到类似Intent的隐式匹配的效果。<br>当然跳转之前还需要做次判断，如果手机中没有安装APP，则跳转到对应的下载网页。</p>
<blockquote>
<p>从网页打开APP，如果没有安装就进行下载。当然，也可以做别的操作处理，比如跳转应用市场一类的详情页面。在此仅提供思路，欢迎发散思维。</p>
</blockquote>
<p>网页唤醒APP，除了安卓外，ios也可以达到同样效果。不过scheme等略有不同，这就需要在网页中去判断当前设备是否是安卓设备。常见的判断方法就是通过网络请求中的UA去判断。</p>
<blockquote>
<p>UA，全称是 User Agent，中文名为用户代理，它是一个特殊字符串头，使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。</p>
</blockquote>
<p>言归正传 ，我们来看一下如何实现</p>
<h1 id="实现"><a href="#实现" class="headerlink" title="实现"></a>实现</h1><h2 id="安卓AndroidMainfext-xml"><a href="#安卓AndroidMainfext-xml" class="headerlink" title="安卓AndroidMainfext.xml"></a>安卓AndroidMainfext.xml</h2><p>首先需要指定要启动哪一个Activity，然后为该activity设置添加intent-filter。<br>在要启动的activity下面添加一个intent-filter。</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"> <span class="tag">&lt;<span class="name">intent-filter</span>&gt;</span></span><br><span class="line">     <span class="tag">&lt;<span class="name">action</span> <span class="attr">android:name</span>=<span class="string">&quot;android.intent.action.VIEW&quot;</span> /&gt;</span></span><br><span class="line">     <span class="tag">&lt;<span class="name">category</span> <span class="attr">android:name</span>=<span class="string">&quot;android.intent.category.DEFAULT&quot;</span> /&gt;</span></span><br><span class="line">     <span class="tag">&lt;<span class="name">category</span> <span class="attr">android:name</span>=<span class="string">&quot;android.intent.category.BROWSABLE&quot;</span> /&gt;</span></span><br><span class="line">     <span class="tag">&lt;<span class="name">data</span> <span class="attr">android:host</span>=<span class="string">&quot;splash&quot;</span> <span class="attr">android:scheme</span>=<span class="string">&quot;vchao&quot;</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">intent-filter</span>&gt;</span></span><br></pre></td></tr></table></figure>

<h2 id="html-网页"><a href="#html-网页" class="headerlink" title="html 网页"></a>html 网页</h2><p>在网页中，我们这里只做了简单的处理，点击的时候进行判断跳转。</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;!doctype <span class="meta-keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">meta</span> <span class="attr">http-equiv</span>=<span class="string">&quot;Content-Type&quot;</span> <span class="attr">content</span>=<span class="string">&quot;text/html; charset=utf-8&quot;</span>&gt;</span></span><br><span class="line"></span><br><span class="line">        <span class="tag">&lt;<span class="name">meta</span> <span class="attr">name</span>=<span class="string">&quot;apple-mobile-web-app-capable&quot;</span> <span class="attr">content</span>=<span class="string">&quot;yes&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">meta</span> <span class="attr">name</span>=<span class="string">&quot;apple-mobile-web-app-status-bar-style&quot;</span> <span class="attr">content</span>=<span class="string">&quot;black&quot;</span>/&gt;</span></span><br><span class="line"></span><br><span class="line">        <span class="tag">&lt;<span class="name">title</span>&gt;</span>唤醒APP<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">meta</span> <span class="attr">id</span>=<span class="string">&quot;viewport&quot;</span> <span class="attr">name</span>=<span class="string">&quot;viewport&quot;</span> <span class="attr">content</span>=<span class="string">&quot;width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,minimal-ui&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">a</span> <span class="attr">id</span>=<span class="string">&quot;J-call-app&quot;</span> <span class="attr">href</span>=<span class="string">&quot;javascript:;&quot;</span> <span class="attr">class</span>=<span class="string">&quot;label&quot;</span>&gt;</span>立即打开<span class="symbol">&amp;gt;</span><span class="symbol">&amp;gt;</span><span class="tag">&lt;/<span class="name">a</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">input</span> <span class="attr">id</span>=<span class="string">&quot;J-download-app&quot;</span> <span class="attr">type</span>=<span class="string">&quot;hidden&quot;</span> <span class="attr">name</span>=<span class="string">&quot;storeurl&quot;</span> <span class="attr">value</span>=<span class="string">&quot;http://m.chanyouji.cn/apk/chanyouji-2.2.0.apk&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"></span><br><span class="line">        <span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="javascript"></span></span><br><span class="line"><span class="javascript">            (<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span></span><br><span class="line"><span class="javascript">                <span class="comment">/*获取UA标识，并转为小写*/</span></span></span><br><span class="line"><span class="javascript">                <span class="keyword">var</span> ua = navigator.userAgent.toLowerCase();</span></span><br><span class="line"><span class="javascript">                <span class="keyword">var</span> t;</span></span><br><span class="line"><span class="javascript">                <span class="keyword">var</span> config = &#123;</span></span><br><span class="line"><span class="javascript">                    <span class="comment">/*scheme:必须*/</span></span></span><br><span class="line"><span class="javascript">                    <span class="attr">scheme_IOS</span>: <span class="string">&#x27;vchao://&#x27;</span>,</span></span><br><span class="line"><span class="javascript">                    <span class="attr">scheme_Adr</span>: <span class="string">&#x27;vchao://splash&#x27;</span>,</span></span><br><span class="line"><span class="javascript">                    <span class="attr">download_url</span>: <span class="built_in">document</span>.getElementById(<span class="string">&#x27;J-download-app&#x27;</span>).value,</span></span><br><span class="line"><span class="javascript">                    <span class="attr">timeout</span>: <span class="number">600</span></span></span><br><span class="line"><span class="javascript">                &#125;;</span></span><br><span class="line"><span class="javascript"></span></span><br><span class="line"><span class="javascript">                <span class="function"><span class="keyword">function</span> <span class="title">openclient</span>(<span class="params"></span>) </span>&#123;</span></span><br><span class="line"><span class="javascript">                    <span class="keyword">var</span> startTime = <span class="built_in">Date</span>.now();</span></span><br><span class="line"><span class="javascript"></span></span><br><span class="line"><span class="javascript">                    <span class="keyword">var</span> ifr = <span class="built_in">document</span>.createElement(<span class="string">&#x27;iframe&#x27;</span>);</span></span><br><span class="line"><span class="javascript">                    </span></span><br><span class="line"><span class="javascript">                    <span class="comment">/*通过UA标识，判断是否是苹果系统*/</span></span></span><br><span class="line"><span class="javascript">                    ifr.src = ua.indexOf(<span class="string">&#x27;os&#x27;</span>) &gt; <span class="number">0</span> ? config.scheme_IOS : config.scheme_Adr;</span></span><br><span class="line"><span class="javascript">                    ifr.style.display = <span class="string">&#x27;none&#x27;</span>;</span></span><br><span class="line"><span class="javascript">                    <span class="built_in">document</span>.body.appendChild(ifr);</span></span><br><span class="line"><span class="javascript"></span></span><br><span class="line"><span class="javascript">                    <span class="keyword">var</span> t = <span class="built_in">setTimeout</span>(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span></span><br><span class="line"><span class="javascript">                        <span class="keyword">var</span> endTime = <span class="built_in">Date</span>.now();</span></span><br><span class="line"><span class="javascript"></span></span><br><span class="line"><span class="javascript">                        <span class="keyword">if</span> (!startTime || endTime - startTime &lt; config.timeout + <span class="number">200</span>) &#123; </span></span><br><span class="line"><span class="javascript">                            <span class="built_in">window</span>.location = config.download_url;</span></span><br><span class="line"><span class="javascript">                        &#125; <span class="keyword">else</span> &#123;</span></span><br><span class="line"><span class="javascript">                            </span></span><br><span class="line"><span class="javascript">                        &#125;</span></span><br><span class="line"><span class="javascript">                    &#125;, config.timeout);</span></span><br><span class="line"><span class="javascript"></span></span><br><span class="line"><span class="javascript">                    <span class="built_in">window</span>.onblur = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span></span><br><span class="line"><span class="javascript">                        <span class="built_in">clearTimeout</span>(t);</span></span><br><span class="line"><span class="javascript">                    &#125;</span></span><br><span class="line"><span class="javascript">                &#125;</span></span><br><span class="line"><span class="javascript">                <span class="built_in">window</span>.addEventListener(<span class="string">&quot;DOMContentLoaded&quot;</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span></span><br><span class="line"><span class="javascript">                    <span class="built_in">document</span>.getElementById(<span class="string">&quot;J-call-app&quot;</span>).addEventListener(<span class="string">&#x27;click&#x27;</span>,openclient,<span class="literal">false</span>);</span></span><br><span class="line"><span class="javascript"></span></span><br><span class="line"><span class="javascript">                &#125;, <span class="literal">false</span>);</span></span><br><span class="line"><span class="javascript">            &#125;)()</span></span><br><span class="line"><span class="javascript">        </span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure>
<h2 id="如果需要传参数。"><a href="#如果需要传参数。" class="headerlink" title="如果需要传参数。"></a>如果需要传参数。</h2><p>在html网页中直接拼接参数。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vchao://splash/?arg0=marc&amp;arg1=xie</span><br></pre></td></tr></table></figure>
<p>在唤醒的activity页面做参数的接收。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">Uri uri = getIntent().getData();  </span><br><span class="line"> <span class="keyword">if</span> (uri != <span class="keyword">null</span>) &#123;  </span><br><span class="line">     String test1 = uri.getQueryParameter(<span class="string">&quot;arg0&quot;</span>);  </span><br><span class="line">     String test2 = uri.getQueryParameter(<span class="string">&quot;arg1&quot;</span>);  </span><br><span class="line">     tv.setText(test1 + test2);  </span><br><span class="line"> &#125;  </span><br></pre></td></tr></table></figure>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://vchao.top/2018/03/12/%E5%AE%89%E5%8D%93%EF%BC%9A%E4%B8%89%E5%88%86%E9%92%9F%E5%AE%9E%E7%8E%B0%E7%89%A9%E6%B5%81%E9%85%8D%E9%80%81%E9%A1%B5%E9%9D%A2%EF%BC%88%E6%97%B6%E9%97%B4%E8%BD%B4%E6%95%88%E6%9E%9C%EF%BC%89/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="vchao">
      <meta itemprop="description" content="怀揣好奇，梦想改变世界的菜鸟极客">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="乘风破浪">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/2018/03/12/%E5%AE%89%E5%8D%93%EF%BC%9A%E4%B8%89%E5%88%86%E9%92%9F%E5%AE%9E%E7%8E%B0%E7%89%A9%E6%B5%81%E9%85%8D%E9%80%81%E9%A1%B5%E9%9D%A2%EF%BC%88%E6%97%B6%E9%97%B4%E8%BD%B4%E6%95%88%E6%9E%9C%EF%BC%89/" class="post-title-link" itemprop="url">安卓：三分钟实现物流配送页面（时间轴效果）</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2018-03-12 18:42:37" itemprop="dateCreated datePublished" datetime="2018-03-12T18:42:37+08:00">2018-03-12</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="far fa-calendar-check"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2021-08-25 22:37:20" itemprop="dateModified" datetime="2021-08-25T22:37:20+08:00">2021-08-25</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Android/" itemprop="url" rel="index"><span itemprop="name">Android</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>﻿&gt; 物流配送页面。主要使用RecycleView实现。通过判断将条目的第一条进行特殊处理。日后复制粘贴备用。效果图如下：</p>
<p><img src="https://upload-images.jianshu.io/upload_images/2533166-d7b586cf5dd2b195.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="查看物流"></p>
<p>可以通过各个view的相对位置来实现啊,比如那一条竖线可以用imageview来实现,那个圆点也可以用imageview实现啊,唯一不同的就是竖线的view是穿过灰色的圆view的,而position为0的竖线是不穿过蓝色的圆view的,这个也有办法搞定,在adapter里面单独处理,设置他们的相对位置! </p>
<h1 id="1-先做两个shape圆"><a href="#1-先做两个shape圆" class="headerlink" title="1. 先做两个shape圆"></a>1. 先做两个shape圆</h1><p>一个灰色的一个红色的。（也可以使用图片资源）<br>红色圆 logistics_shape_circle_red:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;</span><br><span class="line">&lt;shape xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;</span><br><span class="line">    android:shape=&quot;oval&quot;&gt;</span><br><span class="line">    &lt;solid android:color=&quot;#ff4143&quot; /&gt;</span><br><span class="line">    &lt;stroke</span><br><span class="line">        android:width=&quot;2dp&quot;</span><br><span class="line">        android:color=&quot;#ff7471&quot; /&gt;</span><br><span class="line">&lt;/shape&gt;</span><br></pre></td></tr></table></figure>
<p>灰色圆 shape_circle_logistics_gray:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;</span><br><span class="line">&lt;shape xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;</span><br><span class="line">    android:shape=&quot;oval&quot;&gt;</span><br><span class="line">    &lt;solid android:color=&quot;#dddddd&quot; /&gt;</span><br><span class="line">&lt;/shape&gt;</span><br></pre></td></tr></table></figure>
<h1 id="2-设置每个条目的布局"><a href="#2-设置每个条目的布局" class="headerlink" title="2. 设置每个条目的布局"></a>2. 设置每个条目的布局</h1><p>logistics_recycle_item.xml</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br></pre></td><td class="code"><pre><span class="line">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;</span><br><span class="line">&lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;</span><br><span class="line">    android:layout_width=&quot;match_parent&quot;</span><br><span class="line">    android:layout_height=&quot;wrap_content&quot;</span><br><span class="line">    android:orientation=&quot;horizontal&quot;&gt;</span><br><span class="line"></span><br><span class="line">    &lt;!--左边 时间--&gt;</span><br><span class="line">    &lt;TextView</span><br><span class="line">        android:id=&quot;@+id/tv_time&quot;</span><br><span class="line">        android:layout_width=&quot;85dp&quot;</span><br><span class="line">        android:layout_height=&quot;match_parent&quot;</span><br><span class="line">        android:layout_marginLeft=&quot;14dp&quot;</span><br><span class="line">        android:gravity=&quot;center&quot;</span><br><span class="line">        android:lines=&quot;2&quot;</span><br><span class="line">        android:text=&quot;2016-10-12 08:02:18&quot;</span><br><span class="line">        android:textColor=&quot;@color/gray9&quot;</span><br><span class="line">        android:textSize=&quot;16sp&quot; /&gt;</span><br><span class="line">    &lt;!--中间 时间轴--&gt;</span><br><span class="line">    &lt;RelativeLayout</span><br><span class="line">        android:id=&quot;@+id/rl_left&quot;</span><br><span class="line">        android:layout_width=&quot;35dp&quot;</span><br><span class="line">        android:layout_height=&quot;86dp&quot;&gt;</span><br><span class="line"></span><br><span class="line">        &lt;ImageView</span><br><span class="line">            android:id=&quot;@+id/iv_status&quot;</span><br><span class="line">            android:layout_width=&quot;20dp&quot;</span><br><span class="line">            android:layout_height=&quot;20dp&quot;</span><br><span class="line">            android:layout_centerInParent=&quot;true&quot; /&gt;</span><br><span class="line"></span><br><span class="line">        &lt;ImageView</span><br><span class="line">            android:id=&quot;@+id/iv_line&quot;</span><br><span class="line">            android:layout_width=&quot;1dp&quot;</span><br><span class="line">            android:layout_height=&quot;match_parent&quot;</span><br><span class="line">            android:layout_below=&quot;@id/iv_status&quot;</span><br><span class="line">            android:layout_centerInParent=&quot;true&quot;</span><br><span class="line">            android:src=&quot;#dddddd&quot; /&gt;</span><br><span class="line">    &lt;/RelativeLayout&gt;</span><br><span class="line"></span><br><span class="line">    &lt;!--右边 信息--&gt;</span><br><span class="line">    &lt;TextView</span><br><span class="line">        android:id=&quot;@+id/tv_status&quot;</span><br><span class="line">        android:layout_width=&quot;match_parent&quot;</span><br><span class="line">        android:layout_height=&quot;50dp&quot;</span><br><span class="line">        android:layout_gravity=&quot;center_vertical&quot;</span><br><span class="line">        android:layout_marginRight=&quot;15dp&quot;</span><br><span class="line">        android:layout_marginTop=&quot;10dp&quot;</span><br><span class="line">        android:layout_toRightOf=&quot;@id/rl_left&quot;</span><br><span class="line">        android:autoLink=&quot;email|phone|web&quot;</span><br><span class="line">        android:text=&quot;正在派送途中,请您准备签收(派件人:张小建,电话:18513394441)&quot;</span><br><span class="line">        android:textColor=&quot;@color/gray9&quot; /&gt;</span><br><span class="line"></span><br><span class="line">    &lt;TextView</span><br><span class="line">        android:layout_width=&quot;match_parent&quot;</span><br><span class="line">        android:layout_height=&quot;1px&quot;</span><br><span class="line">        android:layout_below=&quot;@id/tv_time&quot;</span><br><span class="line">        android:layout_marginRight=&quot;10dp&quot;</span><br><span class="line">        android:layout_marginTop=&quot;5dp&quot;</span><br><span class="line">        android:layout_toRightOf=&quot;@id/rl_left&quot;</span><br><span class="line">        android:background=&quot;#9b9b9b&quot;</span><br><span class="line">        android:visibility=&quot;gone&quot; /&gt;</span><br><span class="line"></span><br><span class="line">&lt;/LinearLayout&gt;</span><br></pre></td></tr></table></figure>
<h1 id="3-Adapter代码"><a href="#3-Adapter代码" class="headerlink" title="3. Adapter代码"></a>3. Adapter代码</h1><p>LogisticsAdapter.xml</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br></pre></td><td class="code"><pre><span class="line">public class LogisticsAdapter0 extends RecyclerView.Adapter&lt;LogisticsAdapter0.LogisticsAdapterHolder&gt; &#123;</span><br><span class="line"></span><br><span class="line">    private Context context;</span><br><span class="line">    private LayoutInflater mLayoutInflater;</span><br><span class="line">    private LogisticsJson bean;</span><br><span class="line">    </span><br><span class="line">    public LogisticsAdapter0(Context context, LogisticsJson bean) &#123;</span><br><span class="line">        this.context = context;</span><br><span class="line">        this.mLayoutInflater = LayoutInflater.from(context);</span><br><span class="line">        this.bean = bean;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    @Override</span><br><span class="line">    public int getItemCount() &#123;</span><br><span class="line">        return bean.getData().getList().size();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    @Override</span><br><span class="line">    public LogisticsAdapter0.LogisticsAdapterHolder onCreateViewHolder(ViewGroup parent, int viewType) &#123;</span><br><span class="line">        return new LogisticsAdapter0.LogisticsAdapterHolder(mLayoutInflater.inflate(R.layout.logistics_recycle_item, parent, false));</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    @Override</span><br><span class="line">    public void onBindViewHolder(LogisticsAdapter0.LogisticsAdapterHolder holder, int position) &#123;</span><br><span class="line"></span><br><span class="line">        try &#123;</span><br><span class="line">            holder.tv_status.setText(bean.getData().getList().get(position).getContext());//订单状态</span><br><span class="line">            holder.tv_time.setText(bean.getData().getList().get(position).getTime());//时间</span><br><span class="line"></span><br><span class="line">            if (position == 0) &#123;</span><br><span class="line">                //红色的圆点</span><br><span class="line">                holder.iv_status.setImageResource(R.drawable.logistics_shape_circle_red);</span><br><span class="line">                RelativeLayout.LayoutParams pointParams = new RelativeLayout.LayoutParams(DensityUtil.dp2px(context, 20), DensityUtil.dp2px(context, 20));</span><br><span class="line">                pointParams.addRule(RelativeLayout.CENTER_IN_PARENT);</span><br><span class="line">                holder.iv_status.setLayoutParams(pointParams);</span><br><span class="line"></span><br><span class="line">                holder.tv_time.setTextColor(context.getResources().getColor(R.color.newPrimary));</span><br><span class="line">                holder.tv_status.setTextColor(context.getResources().getColor(R.color.newPrimary));</span><br><span class="line"></span><br><span class="line">                //灰色的竖线</span><br><span class="line">                RelativeLayout.LayoutParams lineParams = new RelativeLayout.LayoutParams(DensityUtil.dp2px(context, 1), ViewGroup.LayoutParams.MATCH_PARENT);</span><br><span class="line">                lineParams.addRule(RelativeLayout.BELOW, R.id.iv_status);//让直线置于圆点下面</span><br><span class="line">                lineParams.addRule(RelativeLayout.CENTER_IN_PARENT);</span><br><span class="line">                holder.iv_line.setLayoutParams(lineParams);</span><br><span class="line"></span><br><span class="line">            &#125; else &#123;</span><br><span class="line">//                holder.iv_status.setBackgroundResource(R.mipmap.ic_logistics_bottom);</span><br><span class="line">                holder.iv_status.setImageResource(R.drawable.logistics_shape_circle_gray);</span><br><span class="line">                RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(DensityUtil.dp2px(context, 10), DensityUtil.dp2px(context, 10));</span><br><span class="line">                lp.addRule(RelativeLayout.CENTER_IN_PARENT);</span><br><span class="line"></span><br><span class="line">                holder.iv_status.setLayoutParams(lp);</span><br><span class="line"></span><br><span class="line">                holder.tv_time.setTextColor(context.getResources().getColor(R.color.textColor_9b));</span><br><span class="line">                holder.tv_status.setTextColor(context.getResources().getColor(R.color.textColor_9b));</span><br><span class="line"></span><br><span class="line">                //灰色的竖线</span><br><span class="line">                RelativeLayout.LayoutParams lineParams = new RelativeLayout.LayoutParams(DensityUtil.dp2px(context, 1), ViewGroup.LayoutParams.MATCH_PARENT);</span><br><span class="line">//                lineParams.addRule(RelativeLayout.BELOW, R.id.iv_status);//让直线置于圆点下面</span><br><span class="line">                lineParams.addRule(RelativeLayout.CENTER_IN_PARENT);</span><br><span class="line">                holder.iv_line.setLayoutParams(lineParams);</span><br><span class="line"></span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">        &#125; catch (Exception e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    //自定义的ViewHolder，持有每个Item的的所有界面元素</span><br><span class="line">    public static class LogisticsAdapterHolder extends RecyclerView.ViewHolder &#123;</span><br><span class="line"></span><br><span class="line">        ImageView iv_status;</span><br><span class="line">        TextView tv_status;</span><br><span class="line">        TextView tv_time;</span><br><span class="line">        ImageView iv_line;</span><br><span class="line"></span><br><span class="line">        LogisticsAdapterHolder(View view) &#123;</span><br><span class="line">            super(view);</span><br><span class="line">            iv_line = (ImageView) view.findViewById(R.id.iv_line);</span><br><span class="line">            iv_status = (ImageView) view.findViewById(R.id.iv_status);</span><br><span class="line">            tv_status = (TextView) view.findViewById(R.id.tv_status);</span><br><span class="line">            tv_time = (TextView) view.findViewById(R.id.tv_time);</span><br><span class="line"></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h1 id="4-最后，Activity里面设置一下"><a href="#4-最后，Activity里面设置一下" class="headerlink" title="4. 最后，Activity里面设置一下"></a>4. 最后，Activity里面设置一下</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">LogisticsJson logisticsJson = new Gson().fromJson(json, LogisticsJson.class);</span><br><span class="line">LogisticsAdapter logisticsAdapter = new LogisticsAdapter(LogisticsActivity.this, logisticsJson);</span><br><span class="line">rvLogisticsDetail.setAdapter(logisticsAdapter);</span><br></pre></td></tr></table></figure>


<p>再给一个测试的json，自己生成Gson 的bean类吧！</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">    &quot;code&quot;: 1,</span><br><span class="line">    &quot;message&quot;: &quot;Success&quot;,</span><br><span class="line">    &quot;data&quot;: &#123;</span><br><span class="line">        &quot;id&quot;: &quot;1&quot;,</span><br><span class="line">        &quot;state&quot;: &quot;3&quot;,</span><br><span class="line">        &quot;num&quot;: &quot;71265042088396&quot;,</span><br><span class="line">        &quot;time&quot;: &quot;2018-03-11 12:55:09&quot;,</span><br><span class="line">        &quot;com_name&quot;: &quot;汇通&quot;,</span><br><span class="line">        &quot;list&quot;: [</span><br><span class="line">            &#123;</span><br><span class="line">                &quot;time&quot;: &quot;2018-03-02 08:46:40&quot;,</span><br><span class="line">                &quot;context&quot;: &quot;秦皇岛市|秦皇岛市【秦皇岛市区五部】，八栋西霞超市 已签收&quot;</span><br><span class="line">            &#125;， &#123;</span><br><span class="line">                &quot;time&quot;: &quot;2018-03-02 08:46:40&quot;,</span><br><span class="line">                &quot;context&quot;: &quot;秦皇岛市|秦皇岛市【秦皇岛市区五部】，八栋西霞超市 已签收&quot;</span><br><span class="line">            &#125;</span><br><span class="line">        ]</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>大功告成！复制粘贴大法好~~</p>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://vchao.top/2017/05/12/AS%E9%83%A8%E7%BD%B2%E5%A4%B1%E8%B4%A5%EF%BC%8CDevice%20supports,but%20APK%20only%20supports.../">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="vchao">
      <meta itemprop="description" content="怀揣好奇，梦想改变世界的菜鸟极客">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="乘风破浪">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/2017/05/12/AS%E9%83%A8%E7%BD%B2%E5%A4%B1%E8%B4%A5%EF%BC%8CDevice%20supports,but%20APK%20only%20supports.../" class="post-title-link" itemprop="url">AS部署失败，Device supports,but APK only supports...</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2017-05-12 20:03:39" itemprop="dateCreated datePublished" datetime="2017-05-12T20:03:39+08:00">2017-05-12</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="far fa-calendar-check"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2021-08-25 22:37:20" itemprop="dateModified" datetime="2021-08-25T22:37:20+08:00">2021-08-25</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Android/" itemprop="url" rel="index"><span itemprop="name">Android</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>﻿前几天在公司运行应用发现一个奇葩的问题，居然报了设备不支持的问题。</p>
<p>安装失败：<br><img src="http://img.blog.csdn.net/20171020213237127?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhlbmdfd2VpY2hhbw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="部署不成功"></p>
<p>选择设备：<br><img src="http://img.blog.csdn.net/20171020213358336?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhlbmdfd2VpY2hhbw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="设备不支持"></p>
<p>不支持？莫非是ndk出错了？吓的我还特意去看了看，结果明显已经包含了。<br><img src="http://img.blog.csdn.net/20171020213456097?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhlbmdfd2VpY2hhbw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="ndk"></p>
<p>最后结果：</p>
<blockquote>
<p>主板供电不足，换了根数据线，换到了后面的USB接口，果然好了<del>啧啧</del></p>
</blockquote>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://vchao.top/2017/05/12/Android%20Studio%EF%BC%9A%E6%83%B3%E8%A6%81%E4%BA%8B%E5%8D%8A%E5%8A%9F%E5%80%8D%EF%BC%8C%E4%BD%A0%E9%9C%80%E8%A6%81%E8%AE%B0%E4%BD%8F%E8%BF%99%E4%BA%9B%E5%BF%AB%E6%8D%B7%E9%94%AE/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="vchao">
      <meta itemprop="description" content="怀揣好奇，梦想改变世界的菜鸟极客">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="乘风破浪">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/2017/05/12/Android%20Studio%EF%BC%9A%E6%83%B3%E8%A6%81%E4%BA%8B%E5%8D%8A%E5%8A%9F%E5%80%8D%EF%BC%8C%E4%BD%A0%E9%9C%80%E8%A6%81%E8%AE%B0%E4%BD%8F%E8%BF%99%E4%BA%9B%E5%BF%AB%E6%8D%B7%E9%94%AE/" class="post-title-link" itemprop="url">Android Studio：想要事半功倍，你需要记住这些快捷键</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2017-05-12 20:03:39" itemprop="dateCreated datePublished" datetime="2017-05-12T20:03:39+08:00">2017-05-12</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="far fa-calendar-check"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2021-08-25 22:37:20" itemprop="dateModified" datetime="2021-08-25T22:37:20+08:00">2021-08-25</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Android/" itemprop="url" rel="index"><span itemprop="name">Android</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <blockquote>
<p>恩，我这个人有个癖好，就是爱收集各种快捷键，office，ps一类的快捷键收集了好多。原因嘛，还是那句话，工欲善其事，必先利其器。能有事半功倍的办法，何乐而不为呢？</p>
</blockquote>
<p>我这里只是总结一下经常会使用到的快捷键。但是最好是实践出真知，不要硬性背，或许能够有更好的效果。</p>
<p>|  快捷键  |  功能作用描述 |<br>| ————- |:————-:| —–:|<br>|Ctrl+E|    打开最近操作的文件<br>|Ctrl+Z    |撤销<br>|Ctrl+Shift+Z    |重做(在Eclipse中使用的是Ctrl+Y)<br>|Ctr+Y    |删除该行(Eclipse中的删除该行是Ctrl+D)<br>|Ctrl+D|    向下复制该行<br>|F11    |将鼠标停留的所在行加入书签Bookmarks中，可以使用快捷键Alt+2查看所有的书签以及Favorites和断点BreakPoints<br>|Ctrl+Alt+向左/右箭头    |遍历你的导航操作(如光标移动、选项卡切换和文件打开)<br>|Alt+左右箭头    |可以在所有已经打开的文件中左右切换<br>|Alt+数字1、2、3、4、5、6···    |可以打开相对应的工具按钮(分布在Android Studio的左、下、右边边，并且其中一些按钮还有一个对应的小数字)，使用Alt+对应的数字|就能打开或者关闭这些按钮了<br>|Ctrl+Shift+V    |复制历史记录<br>|Ctrl+Alt+Shift+C    |复制方法、变量、或类的逻辑引用，当把此引用粘贴到另一个源文件中时能够自动导入所需的限定符和导入语句<br>|Ctrl+Shift+A    |弹出的搜索框中输入你想搜索的内容(Android Studio的具备的特性、功能)，系统会给出结果，这货很有用<br>|Alt+F1    |出现Select In 对话框，可以进行一些便捷的操作，虽然好用但是还不如用鼠标<br>|Ctrl+N    |在弹出的对话框中输入类的名字可以直接打开该类，超赞<br>|Ctrl+Shift+N    |在弹出的对话框中输入文件的名字可以直接打开该文件，比起上一个能打开的文件更多<br>|Ctrl+G    |可以输入想要到达的行数或者行数:列数，文件很长的时候很有用<br>|Ctrl+Alt+Home    |可以打开与当前文件相关联的文件，例如打开的MainActivity.java，那么他的相关文件就会是activity_main.xml ,你的同事绝对不知道这一点<br>|Ctrl+H|    可以查看当前类(只有在java文件中有效)的继承关系，你会发现不出意外的话Alt+8 与其效果是同样的<br>|Ctrl+数字加号    |展开光标所在处已折叠的代码块<br>|Ctrl+数字减号|    折叠光标所在处已展开的代码块<br>|Ctrl+Shift+数字加号    |展开所有已折叠的代码块<br>|Ctrl+Shift+数字减号|    折叠所有已展开的代码块<br>|Ctrl+空格|    代码提示，但是Windows系统下好像是输入法的切换，如果你还是想使用这个快捷键，要么将其改为Ctrl+3，要么就修改注册表咯。方法1，方法2<br>|Alt+Enter    |绝对是用的最多的，可以自动补全当行并且将光标跳到下一行，当新引入一个类但是还没有导入的时候，只需要对着类的名字使用该快捷键就可以自动导入了<br>|Shift+Enter    |直接从当前行跳转到下一行，不用将光标置于当前行末尾然后再按回车，十分方便<br>|Alt+/|    同样也是代码提示，不过这个提示只是提供在文件中使用过的单词，向上循环<br>|Alt+Shift+/|    还是代码提示，提示只提供在文件中使用过的单词，向下循环<br>|Ctrl+/|    代码注释，适用于单行，也可以选择多行，用得最多的了，不用我强调的啦<br>|Ctrl+Shift+/|  块注释<br>|Alt+Insert|    呼出Generate命令<br>|Ctrl+J    |插入代码模板，或者如果你记得代码模板的名称，例如fbc，接着是用Ctrl+J，则可以直接插入() findViewById(R.id.)<br>|Ctrl+Alt+J    |当选择一个单词之后使用该快捷键可以直接呼出模板，选择其中你需要的就行了<br>|Ctrl+Shift+向上箭头/向下箭头    |在作用域的范围内上/下移一条或多条语句，如果移动的是代码块，则整个代码块将会一起移动到下一个语法正确的位置<br>|Alt+Shift+向上箭头/向下箭头|    将一条或多条语句向上/下移动而不考虑作用范围以及语法是否正确<br>|Ctrl+Alt+I    |根据Code Style 中设置的方案，对当前鼠标所在的行或选中的多行进行缩进，保持代码美观很有效<br>|Ctrl+Alt+O    |组织导入语句<br>|Ctrl+Alt+L|    对文件的代码格式进行重新的整理<br>|Ctrl+Alt+T    |选中需要包裹的语句，使用该快捷键可以快速的将其被try catch，if/else，for或者for each 等包裹，用熟了会很方便<br>|Ctrl+Shift+Delete|    选中不想被包裹的语句，使用改快捷键可以删除try catch，if/else，for或者for each等代码块<br>|Ctrl+Alt+Shift+T|    呼出Refactor This对话框，可以做很多有关重构的事情，四个快捷键可以记住成CAST<br>|Shift+F6|    重命名该文件<br>|Ctrl+F6    |修改方法名以及参数<br>|Ctrl+Shift+F6|    类型迁移<br>|F6|    移动文件或者移动变量到另一个文件<br>|F5    |复制文件或者复制变量到另一个文件<br>|Home|    将光标置于当前行的首个字母前<br>|End    |将光标置于当前行的末尾<br>|Ctrl+Alt+V    |抽取变量(variable)<br>|Ctrl+Alt+C|    抽取常量(constant)<br>|Ctrl+Alt+F    |抽取字段(filed)<br>|Ctrl+Alt+P    |抽取参数(parameter)<br>|Ctrl+Alt+M    |抽取方法(Method)<br>|Ctrl+K    |Git提交修改<br>|Shift+F10    |运行项目<br>|Ctrl+Alt+S    |设置<br>|Ctrl+Alt+Shift+S    |项目结构设置</p>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://vchao.top/2017/05/12/Kotlin%E6%98%AF%E4%B8%AA%E4%BB%80%E4%B9%88%E4%B8%9C%E4%B8%9C%EF%BC%9F/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="vchao">
      <meta itemprop="description" content="怀揣好奇，梦想改变世界的菜鸟极客">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="乘风破浪">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/2017/05/12/Kotlin%E6%98%AF%E4%B8%AA%E4%BB%80%E4%B9%88%E4%B8%9C%E4%B8%9C%EF%BC%9F/" class="post-title-link" itemprop="url">Kotlin是个什么东东？</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2017-05-12 20:03:39" itemprop="dateCreated datePublished" datetime="2017-05-12T20:03:39+08:00">2017-05-12</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="far fa-calendar-check"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2021-08-25 22:37:20" itemprop="dateModified" datetime="2021-08-25T22:37:20+08:00">2021-08-25</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Android/" itemprop="url" rel="index"><span itemprop="name">Android</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>仿佛是一夜之间，突然就好多人都在讨论Kotlin，一下子就把我弄懵逼了，这是个什么东东？？然后各种百度，看各种大佬的文章，最后整理成了自己的理解。这篇文章就来简单讲一下，不对的地方，欢迎大家指出来。</p>
<h2 id="百度百科："><a href="#百度百科：" class="headerlink" title="百度百科："></a>百度百科：</h2><p><strong>Kotlin</strong><br>    1.Kotlin 是一个基于 JVM 的新的编程语言，由 JetBrains 开发。Kotlin可以编译成Java字节码，也可以编译成JavaScript，方便在没有JVM的设备上运行。<br>    2. JetBrains，作为目前广受欢迎的Java IDE IntelliJ 的提供商，在 Apache 许可下已经开源其Kotlin 编程语言。Kotlin已正式成为Android官方开发语言。</p>
<h2 id="官方资料"><a href="#官方资料" class="headerlink" title="官方资料"></a>官方资料</h2><p>了解Kotlin的话，还是推荐大家先从官方资料入手。别人的理解多少总会有些偏差的。</p>
<ul>
<li>首发kotlin的官方github地址了：<a target="_blank" rel="noopener" href="https://github.com/JetBrains/kotlin">github地址</a></li>
<li>英语不好的话，就乖乖看官方中文翻译站点吧：<a target="_blank" rel="noopener" href="https://www.kotlincn.net/docs/reference/">官方中文翻译</a></li>
</ul>
<h2 id="鸿洋大神："><a href="#鸿洋大神：" class="headerlink" title="鸿洋大神："></a>鸿洋大神：</h2><ol>
<li>有着扎实的Java基础，这东西学习起来肯定是可以速成的，所以不要惊慌，如果有着原本的学习计划，也不用着急着打乱自己原本的节奏（不反对立即开始学习的哈，为爱学习的点赞）~</li>
<li>一个新的语言想要快速的普及，那么可能只有在运行效率上提升那才是最大的优势，如果说：“XX语言被Android官方支持，运行速度比原本提升50%”，那么不用想，立即去学习（Kotlin并不具备这样的属性，而且其所表现出类似于“简洁”这样的优势，短期内在一个多年Java的开发者面前，是体现不出来的）。</li>
<li>所以，Kotlin肯定是值得学习的，但并没有传的那么夸张。有精力就去学习，有自己的学习计划也可以放一放。</li>
<li>我想只有用得多了，Kotlin的优势应该会慢慢展现出来的，但是应该需要一个较为漫长的过渡期（如果有公司内部支持，那么这个过程肯定很快）~</li>
</ol>
<p>然后鸿洋大神推荐了好多Kotlin的学习资料~~恩，大家有意愿的可以戳这里。<a target="_blank" rel="noopener" href="http://mp.weixin.qq.com/s?__biz=MzAxMTI4MTkwNQ==&mid=2650823035&idx=1&sn=2db4eea9eb569bf375f847f36b1229fa&chksm=80b78de5b7c004f3c3f0a54b535671971f91708def1faecb4b1a4628bb7efb9d00392f11beca&mpshare=1&scene=1&srcid=0519TOOTzQt3M6JPHUknxKC9#rd">学习Kotlin吗？</a></p>
<h2 id="张涛大神"><a href="#张涛大神" class="headerlink" title="张涛大神"></a>张涛大神</h2><p>1.如果一门编程语言不足以改变你的编程思维，那么它是失败的。我们已经熟练了C、Obj-C、JAVA等静态语言，是时候学习一下Swift、Go、Kotlin这种动态语言了（只是语法上类似动态语言的语法）。<br>2.第二个原因，Kotlin确实能省略许多的代码编写，以及它特有的语言特性。 第三个原因，与Sala、Go等相比，Kotlin能够完美兼容现有的Java代码，也就是说，像我们平时使用的Volley、KJFrameForAndroid、OKHttp等开发框架，在Kotlin语言下依旧能正常运行。</p>
<p>恩，附上张涛大神的博客地址。里面好多kotlin的教程。<a target="_blank" rel="noopener" href="https://kymjs.com/column/kotlin.html">开源实验室</a></p>
<h2 id="大精-wing的地方酒馆"><a href="#大精-wing的地方酒馆" class="headerlink" title="大精-wing的地方酒馆"></a>大精-wing的地方酒馆</h2><pre><code>至于Kotlin是什么，简单的说就是跑在jvm上的新语言，他的特点就是短小 ~~快~~，至于有什么好处，那就说不完啊，挑特点来说。
1.无缝对接java，可以java代码和kotlin代码互相调用
2.一键java转kotlin，如果你有遗留的java代码，可以一键转换
3.函数扩展功能，再也不知道啥叫继承
</code></pre>
<p><a target="_blank" rel="noopener" href="http://androidwing.net/index.php/89">让你的代码量减少3倍！使用kotlin开发Android系列</a></p>
<h2 id="我的理解"><a href="#我的理解" class="headerlink" title="我的理解"></a>我的理解</h2><p>1.首先对于我这菜鸟来说，目前并不打算去投入大量精力去学习Kotlin,但肯定会了解下简单的语法，不至于再一脸懵逼。（我的爬坑之路任重而道远啊！）<br>2.既然官方都支持了，那么我们没有理由不去学习，只有不断学习，才能不被这个社会淘汰。Kotlin的简洁，轻，快，会带来许多好处。翟刚大神也说过，不要和版本作对。<br>3.恩……就是这样。</p>

      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  

      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://vchao.top/2017/05/12/%E4%BB%8E%E6%BA%90%E7%A0%81%E6%9D%A5%E7%9C%8BgetReadableDatabase()%E7%9A%84%E8%AF%AF%E5%8C%BA/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="vchao">
      <meta itemprop="description" content="怀揣好奇，梦想改变世界的菜鸟极客">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="乘风破浪">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          
            <a href="/2017/05/12/%E4%BB%8E%E6%BA%90%E7%A0%81%E6%9D%A5%E7%9C%8BgetReadableDatabase()%E7%9A%84%E8%AF%AF%E5%8C%BA/" class="post-title-link" itemprop="url">从源码来看getReadableDatabase()的误区</a>
        </h2>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2017-05-12 20:03:39" itemprop="dateCreated datePublished" datetime="2017-05-12T20:03:39+08:00">2017-05-12</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="far fa-calendar-check"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2021-08-25 22:37:20" itemprop="dateModified" datetime="2021-08-25T22:37:20+08:00">2021-08-25</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Android/" itemprop="url" rel="index"><span itemprop="name">Android</span></a>
                </span>
            </span>

          

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
          <p>﻿### android中使用SQLiteOpenHelper这个辅助类时，可以生成一个数据库，并可以对数据库进行管理的方法可以是?</p>
<blockquote>
<p>A. getWriteableDatabase()<br>B. getReadableDatabase()<br>C. getDatabase()<br>D. getAbleDatabase()</p>
</blockquote>
<p>答案：AB<br>这道题的其实不算难，纯猜也可以猜出来是AB。但是我以前一直以为getReadableDatabase()是以只读方式打开数据库。这就尴尬了。</p>
<h4 id="解析"><a href="#解析" class="headerlink" title="解析"></a>解析</h4><p>Android使用 getWritableDatabase() 和getReadableDatabase()方法都可以获取一个用于操作数据库的SQLiteDatabase实例。(getReadableDatabase()方法中会调用getWritableDatabase()方法)<br><strong>getReadableDatabase()并不是以只读方式打开数据库，而是先执行getWritableDatabase()，失败的情况下才以只读方式打开数据库.。</strong><br>但getWritableDatabase()方法以读写方式打开数据库，一旦数据库的磁盘空间满了，数据库就只能读而不能写，<br>getWritableDatabase()打开数据库就会出错。getReadableDatabase()方法先以读写方式打开数据库，<br>倘若使用如果数据库的磁盘空间满了，就会打开失败，当打开失败后会继续尝试以只读方式打开数据库。</p>
<h4 id="这是我翻译之后的"><a href="#这是我翻译之后的" class="headerlink" title="这是我翻译之后的~~"></a>这是我翻译之后的~~</h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line">	* 创建或者打开一个用于读写的数据库。一旦成功打开，数据库就会被缓存。所以每次你想写入数据库时，都需要调用此方法。当你不再需要时，请确保调用&#123;@link #close&#125;关闭这个数据库。如果权限不足或数据库的磁盘空间满了，可能导致此操作失败，但如果问题是固定的，未来的尝试可能会成功。</span><br><span class="line">	* @throws 如果数据库不能用于写入，则抛出SQLiteException。</span><br><span class="line">	* @return 返回一个读/写数据库对象，直到调用&#123;@link #close&#125;关闭数据库。</span><br><span class="line">    */</span><br><span class="line">    public synchronized SQLiteDatabase getWritableDatabase() &#123;</span><br><span class="line">        if (mDatabase != null &amp;&amp; mDatabase.isOpen() &amp;&amp; !mDatabase.isReadOnly()) &#123;</span><br><span class="line">            return mDatabase;  // 数据库已经被打开了。</span><br><span class="line">        &#125;</span><br><span class="line">        if (mIsInitializing) &#123;</span><br><span class="line">            throw new IllegalStateException(&quot;getWritableDatabase called recursively&quot;);</span><br><span class="line">        &#125;</span><br><span class="line">        // 如果我们打开了一个只读数据库，别人就可以使用它(即使他们不应该)，这会导致文件上被锁定，我们打开数据库读写的尝试将会失败，等待文件锁定。为了防止这种情况发生，我们获取了只读数据库上的锁，让它关闭其他用户。</span><br><span class="line">		</span><br><span class="line">        boolean success = false;</span><br><span class="line">        SQLiteDatabase db = null;</span><br><span class="line">        if (mDatabase != null) mDatabase.lock();</span><br><span class="line">        try &#123;</span><br><span class="line">            mIsInitializing = true;</span><br><span class="line">            if (mName == null) &#123;</span><br><span class="line">                db = SQLiteDatabase.create(null);</span><br><span class="line">            &#125; else &#123;</span><br><span class="line">                db = mContext.openOrCreateDatabase(mName, 0, mFactory);</span><br><span class="line">            &#125;</span><br><span class="line">            int version = db.getVersion();</span><br><span class="line">            if (version != mNewVersion) &#123;</span><br><span class="line">                db.beginTransaction();</span><br><span class="line">                try &#123;</span><br><span class="line">                    if (version == 0) &#123;</span><br><span class="line">                        onCreate(db);</span><br><span class="line">                    &#125; else &#123;</span><br><span class="line">                        onUpgrade(db, version, mNewVersion);</span><br><span class="line">                    &#125;</span><br><span class="line">                    db.setVersion(mNewVersion);</span><br><span class="line">                    db.setTransactionSuccessful();</span><br><span class="line">                &#125; finally &#123;</span><br><span class="line">                    db.endTransaction();</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            onOpen(db);</span><br><span class="line">            success = true;</span><br><span class="line">            return db;</span><br><span class="line">        &#125; finally &#123;</span><br><span class="line">            mIsInitializing = false;</span><br><span class="line">            if (success) &#123;</span><br><span class="line">                if (mDatabase != null) &#123;</span><br><span class="line">                    try &#123; mDatabase.close(); &#125; catch (Exception e) &#123; &#125;</span><br><span class="line">                    mDatabase.unlock();</span><br><span class="line">                &#125;</span><br><span class="line">                mDatabase = db;</span><br><span class="line">            &#125; else &#123;</span><br><span class="line">                if (mDatabase != null) mDatabase.unlock();</span><br><span class="line">                if (db != null) db.close();</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    /**</span><br><span class="line">	 * 创建或打开一个数据库。这将和&#123;@link #getWritableDatabase&#125;返回相同的对象，除非出现某个问题(如磁盘空间已满)数据库只能打开为只读。在这种情况下，将返回一个只读数据库对象。如果问题是固定的，将来调用&#123;@link #getWritableDatabase&#125;可能会成功，此时，只读数据库对象会被关闭，返回读写对象。</span><br><span class="line">     * @throws 如果数据库不能打开，会抛出SQLiteException。</span><br><span class="line">     * @return 在调用&#123;@link #getWritableDatabase&#125;或&#123;@link #close&#125;之前，数据库对象是有效的。</span><br><span class="line">     */</span><br><span class="line">    public synchronized SQLiteDatabase getReadableDatabase() &#123;</span><br><span class="line">        if (mDatabase != null &amp;&amp; mDatabase.isOpen()) &#123;</span><br><span class="line">            return mDatabase;  // 数据库已经被打开了。</span><br><span class="line">        &#125;</span><br><span class="line">        if (mIsInitializing) &#123;</span><br><span class="line">            throw new IllegalStateException(&quot;getReadableDatabase called recursively&quot;);</span><br><span class="line">        &#125;</span><br><span class="line">        try &#123;</span><br><span class="line">            return getWritableDatabase();</span><br><span class="line">        &#125; catch (SQLiteException e) &#123;</span><br><span class="line">            if (mName == null) throw e;  // 不能以只读方式打开缓存数据库！</span><br><span class="line">            Log.e(TAG, &quot;Couldn&#x27;t open &quot; + mName + &quot; for writing (will try read-only):&quot;, e);</span><br><span class="line">        &#125;</span><br><span class="line">        SQLiteDatabase db = null;</span><br><span class="line">        try &#123;</span><br><span class="line">            mIsInitializing = true;</span><br><span class="line">            String path = mContext.getDatabasePath(mName).getPath();</span><br><span class="line">            db = SQLiteDatabase.openDatabase(path, mFactory, SQLiteDatabase.OPEN_READONLY);</span><br><span class="line">            if (db.getVersion() != mNewVersion) &#123;</span><br><span class="line">                throw new SQLiteException(&quot;Can&#x27;t upgrade read-only database from version &quot; +</span><br><span class="line">                        db.getVersion() + &quot; to &quot; + mNewVersion + &quot;: &quot; + path);</span><br><span class="line">            &#125;</span><br><span class="line">            onOpen(db);</span><br><span class="line">            Log.w(TAG, &quot;Opened &quot; + mName + &quot; in read-only mode&quot;);</span><br><span class="line">            mDatabase = db;</span><br><span class="line">            return mDatabase;</span><br><span class="line">        &#125; finally &#123;</span><br><span class="line">            mIsInitializing = false;</span><br><span class="line">            if (db != null &amp;&amp; db != mDatabase) db.close();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>




<h4 id="源码如下："><a href="#源码如下：" class="headerlink" title="源码如下："></a>源码如下：</h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line">     * Create and/or open a database that will be used for reading and writing.</span><br><span class="line">     * Once opened successfully, the database is cached, so you can call this</span><br><span class="line">     * method every time you need to write to the database.  Make sure to call</span><br><span class="line">     * &#123;@link #close&#125; when you no longer need it.</span><br><span class="line">     *</span><br><span class="line">     * &lt;p&gt;Errors such as bad permissions or a full disk may cause this operation</span><br><span class="line">     * to fail, but future attempts may succeed if the problem is fixed.&lt;/p&gt;</span><br><span class="line">     *</span><br><span class="line">     * @throws SQLiteException if the database cannot be opened for writing</span><br><span class="line">     * @return a read/write database object valid until &#123;@link #close&#125; is called</span><br><span class="line">     */</span><br><span class="line">    public synchronized SQLiteDatabase getWritableDatabase() &#123;</span><br><span class="line">        if (mDatabase != null &amp;&amp; mDatabase.isOpen() &amp;&amp; !mDatabase.isReadOnly()) &#123;</span><br><span class="line">            return mDatabase;  // The database is already open for business</span><br><span class="line">        &#125;</span><br><span class="line">        if (mIsInitializing) &#123;</span><br><span class="line">            throw new IllegalStateException(&quot;getWritableDatabase called recursively&quot;);</span><br><span class="line">        &#125;</span><br><span class="line">        // If we have a read-only database open, someone could be using it</span><br><span class="line">        // (though they shouldn&#x27;t), which would cause a lock to be held on</span><br><span class="line">        // the file, and our attempts to open the database read-write would</span><br><span class="line">        // fail waiting for the file lock.  To prevent that, we acquire the</span><br><span class="line">        // lock on the read-only database, which shuts out other users.</span><br><span class="line">        boolean success = false;</span><br><span class="line">        SQLiteDatabase db = null;</span><br><span class="line">        if (mDatabase != null) mDatabase.lock();</span><br><span class="line">        try &#123;</span><br><span class="line">            mIsInitializing = true;</span><br><span class="line">            if (mName == null) &#123;</span><br><span class="line">                db = SQLiteDatabase.create(null);</span><br><span class="line">            &#125; else &#123;</span><br><span class="line">                db = mContext.openOrCreateDatabase(mName, 0, mFactory);</span><br><span class="line">            &#125;</span><br><span class="line">            int version = db.getVersion();</span><br><span class="line">            if (version != mNewVersion) &#123;</span><br><span class="line">                db.beginTransaction();</span><br><span class="line">                try &#123;</span><br><span class="line">                    if (version == 0) &#123;</span><br><span class="line">                        onCreate(db);</span><br><span class="line">                    &#125; else &#123;</span><br><span class="line">                        onUpgrade(db, version, mNewVersion);</span><br><span class="line">                    &#125;</span><br><span class="line">                    db.setVersion(mNewVersion);</span><br><span class="line">                    db.setTransactionSuccessful();</span><br><span class="line">                &#125; finally &#123;</span><br><span class="line">                    db.endTransaction();</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            onOpen(db);</span><br><span class="line">            success = true;</span><br><span class="line">            return db;</span><br><span class="line">        &#125; finally &#123;</span><br><span class="line">            mIsInitializing = false;</span><br><span class="line">            if (success) &#123;</span><br><span class="line">                if (mDatabase != null) &#123;</span><br><span class="line">                    try &#123; mDatabase.close(); &#125; catch (Exception e) &#123; &#125;</span><br><span class="line">                    mDatabase.unlock();</span><br><span class="line">                &#125;</span><br><span class="line">                mDatabase = db;</span><br><span class="line">            &#125; else &#123;</span><br><span class="line">                if (mDatabase != null) mDatabase.unlock();</span><br><span class="line">                if (db != null) db.close();</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    /**</span><br><span class="line">     * Create and/or open a database.  This will be the same object returned by</span><br><span class="line">     * &#123;@link #getWritableDatabase&#125; unless some problem, such as a full disk,</span><br><span class="line">     * requires the database to be opened read-only.  In that case, a read-only</span><br><span class="line">     * database object will be returned.  If the problem is fixed, a future call</span><br><span class="line">     * to &#123;@link #getWritableDatabase&#125; may succeed, in which case the read-only</span><br><span class="line">     * database object will be closed and the read/write object will be returned</span><br><span class="line">     * in the future.</span><br><span class="line">     *</span><br><span class="line">     * @throws SQLiteException if the database cannot be opened</span><br><span class="line">     * @return a database object valid until &#123;@link #getWritableDatabase&#125;</span><br><span class="line">     *     or &#123;@link #close&#125; is called.</span><br><span class="line">     */</span><br><span class="line">    public synchronized SQLiteDatabase getReadableDatabase() &#123;</span><br><span class="line">        if (mDatabase != null &amp;&amp; mDatabase.isOpen()) &#123;</span><br><span class="line">            return mDatabase;  // The database is already open for business</span><br><span class="line">        &#125;</span><br><span class="line">        if (mIsInitializing) &#123;</span><br><span class="line">            throw new IllegalStateException(&quot;getReadableDatabase called recursively&quot;);</span><br><span class="line">        &#125;</span><br><span class="line">        try &#123;</span><br><span class="line">            return getWritableDatabase();</span><br><span class="line">        &#125; catch (SQLiteException e) &#123;</span><br><span class="line">            if (mName == null) throw e;  // Can&#x27;t open a temp database read-only!</span><br><span class="line">            Log.e(TAG, &quot;Couldn&#x27;t open &quot; + mName + &quot; for writing (will try read-only):&quot;, e);</span><br><span class="line">        &#125;</span><br><span class="line">        SQLiteDatabase db = null;</span><br><span class="line">        try &#123;</span><br><span class="line">            mIsInitializing = true;</span><br><span class="line">            String path = mContext.getDatabasePath(mName).getPath();</span><br><span class="line">            db = SQLiteDatabase.openDatabase(path, mFactory, SQLiteDatabase.OPEN_READONLY);</span><br><span class="line">            if (db.getVersion() != mNewVersion) &#123;</span><br><span class="line">                throw new SQLiteException(&quot;Can&#x27;t upgrade read-only database from version &quot; +</span><br><span class="line">                        db.getVersion() + &quot; to &quot; + mNewVersion + &quot;: &quot; + path);</span><br><span class="line">            &#125;</span><br><span class="line">            onOpen(db);</span><br><span class="line">            Log.w(TAG, &quot;Opened &quot; + mName + &quot; in read-only mode&quot;);</span><br><span class="line">            mDatabase = db;</span><br><span class="line">            return mDatabase;</span><br><span class="line">        &#125; finally &#123;</span><br><span class="line">            mIsInitializing = false;</span><br><span class="line">            if (db != null &amp;&amp; db != mDatabase) db.close();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>


      
    </div>

    
    
    
      <footer class="post-footer">
        <div class="post-eof"></div>
      </footer>
  </article>
  
  
  


  
  <nav class="pagination">
    <a class="extend prev" rel="prev" href="/page/3/"><i class="fa fa-angle-left" aria-label="上一页"></i></a><a class="page-number" href="/">1</a><span class="space">&hellip;</span><a class="page-number" href="/page/3/">3</a><span class="page-number current">4</span><a class="page-number" href="/page/5/">5</a><a class="extend next" rel="next" href="/page/5/"><i class="fa fa-angle-right" aria-label="下一页"></i></a>
  </nav>



          </div>
          

<script>
  window.addEventListener('tabs:register', () => {
    let { activeClass } = CONFIG.comments;
    if (CONFIG.comments.storage) {
      activeClass = localStorage.getItem('comments_active') || activeClass;
    }
    if (activeClass) {
      let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
      if (activeTab) {
        activeTab.click();
      }
    }
  });
  if (CONFIG.comments.storage) {
    window.addEventListener('tabs:click', event => {
      if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
      let commentClass = event.target.classList[1];
      localStorage.setItem('comments_active', commentClass);
    });
  }
</script>

        </div>
          
  
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">
    <div class="sidebar-inner">

      <ul class="sidebar-nav motion-element">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <!--noindex-->
      <div class="post-toc-wrap sidebar-panel">
      </div>
      <!--/noindex-->

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
  <p class="site-author-name" itemprop="name">vchao</p>
  <div class="site-description" itemprop="description">怀揣好奇，梦想改变世界的菜鸟极客</div>
</div>
<div class="site-state-wrap motion-element">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/archives/">
        
          <span class="site-state-item-count">46</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
        <span class="site-state-item-count">4</span>
        <span class="site-state-item-name">分类</span>
      </div>
      <div class="site-state-item site-state-tags">
        <span class="site-state-item-count">27</span>
        <span class="site-state-item-name">标签</span>
      </div>
  </nav>
</div>



      </div>

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer class="footer">
      <div class="footer-inner">
        

        
  <div class="beian"><a href="https://beian.miit.gov.cn/" rel="noopener" target="_blank">冀ICP备 17022751号-1 </a>
      <img src="https://beian.miit.gov.cn" style="display: inline-block;">
  </div>

<div class="copyright">
  
  &copy; 
  <span itemprop="copyrightYear">2021</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">vchao</span>
</div>
  <div class="powered-by">由 <a href="https://hexo.io/" class="theme-link" rel="noopener" target="_blank">Hexo</a> & <a href="https://muse.theme-next.org/" class="theme-link" rel="noopener" target="_blank">NexT.Muse</a> 强力驱动
  </div>

        








      </div>
    </footer>
  </div>

  
  <script src="/lib/anime.min.js"></script>
  <script src="/lib/velocity/velocity.min.js"></script>
  <script src="/lib/velocity/velocity.ui.min.js"></script>

<script src="/js/utils.js"></script>

<script src="/js/motion.js"></script>


<script src="/js/schemes/muse.js"></script>


<script src="/js/next-boot.js"></script>




  















  

  

</body>
</html>
